89.如何使用 Redis 实现消息队列?
一般使用 list 结构作为队列,rpush 生产消息,lpop 消费消息。当 lpop 没有消息的时候,要适当 sleep 一会再重试。
如果对方追问可不可以不用 sleep 呢?list 还有个指令叫 blpop ,在没有消息的时候,它会阻塞住直到消息到来。
如果对方追问能不能生产一次消费多次呢?使用 pub / sub 主题订阅者模式,可以实现 1:N 的消息队列。
如果对方追问 pub / sub 有什么缺点?在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如 rabbitmq 等。
之前生产中,就碰到因为网络闪断,导致订阅的 pub/sub 消息丢失,导致 JVM 应用的数据字典和系统参数等缓存未刷新,业务受到影响。所以,最好还是使用专业的消息队列的订阅功能(广播消费)。
如果对方追问 redis 如何实现延时队列?我估计现在你很想把面试官一棒打死如果你手上有一根棒球棍的话,怎么问的这么详细。但是你很克制,然后神态自若的回答道:使用 sortedset ,拿时间戳作为 score ,消息内容作为 key 调用 zadd 来生产消息,消费者用 zrangebyscore 指令获取 N 秒之前的数据轮询进行处理。
可能很多胖友会觉得抽象,可以看看 《Redis 学习笔记之延时队列》 。面试中,能回答到 Redis zset 实现延迟队列,还是蛮加分的。
到这里,面试官暗地里已经对你竖起了大拇指。但是他不知道的是此刻你却竖起了中指,在椅子背后。
当然,实际上 Redis 真的真的真的不推荐作为消息队列使用,它最多只是消息队列的存储层,上层的逻辑,还需要做大量的封装和支持。
另外,在 Redis 5.0 增加了 Stream 功能,一个新的强大的支持多播的可持久化的消息队列,提供类似 Kafka 的功能。