Redis做消息中间件其实挺有意思,聊聊它的消息队列和实现原理
- 问答
- 2026-01-17 18:01:14
- 2
说到消息中间件,大家通常会想到专业的家伙,比如RabbitMQ、Kafka这些,但你可能不知道,我们平时用来存缓存、速度飞快的Redis,其实也能客串一把消息中间件,而且用起来还挺简单、挺有意思的,它就像一把瑞士军刀,除了主刀,还能临时当个螺丝刀用用,解决一些不那么复杂但很实际的通信问题。
Redis是怎么扮演消息中间件的?核心就靠它的“发布订阅”和“列表”这两个数据结构。
先聊聊最像消息队列的“发布订阅”(Pub/Sub),这个模式特别好理解,就像一群人关注了一个微博大V,这里有几个角色:
- 发布者(Publisher):就是那个发微博的大V。
- 频道(Channel):相当于微博的话题标签,今日新鲜事#。
- 订阅者(Subscriber):就是关注了这个话题标签的粉丝。
它的工作流程很直接(根据《Redis设计与实现》书中对Pub/Sub机制的描述),我有一个聊天室应用,我创建一个频道叫 #chat_room_1,用户A和用户B通过执行 SUBSCRIBE #chat_room_1 命令订阅了这个频道,他们就成了订阅者,然后会一直等待这个频道的消息,这时候,用户C想发言,他执行 PUBLISH #chat_room_1 "大家好!",Redis服务器一收到这个命令,立刻就会把“大家好!”这个消息推送给所有订阅了 #chat_room_1 频道的用户(A和B),这个过程是实时的,而且是广播性质的,一条消息会给到所有订阅者。

Pub/Sub模式虽然快,但它有个特点:不持久化,什么意思呢?还拿微博比喻,如果用户D在用户A和B关注话题之前发了一条微博,那A和B是看不到这条历史消息的,同样,如果当时用户A的客户端刚好断线了,等他重连上来,他也会错过断线期间别人发的所有消息,所以它适合那种对消息丢失不那么敏感、强调实时性的场景,比如实时通知、简单的聊天室。
那如果我想让消息更可靠,不怕丢失该怎么办呢?这时候就要请出Redis的“列表”(List)结构了。
List做消息队列,思路就和Pub/Sub不一样了,它更像是我们去银行排队办业务,或者一个任务清单,这里也有角色:

- 生产者(Producer):往队伍末尾排队的人,或者往清单上写任务的人。
- 消费者(Consumer):柜台叫号办理业务的人,或者从清单上领取任务去完成的人。
它的实现主要靠两个命令(根据Redis官方文档对LPUSH、BRPOP等命令的说明):
- 生产者用
LPUSH命令,把一个消息从列表的左侧推进去。 - 消费者用
BRPOP命令,从列表的右侧弹出一条消息来处理,这个“B”代表阻塞(Block),意思是如果列表是空的,没消息可拿,消费者就会乖乖地在那里等着,直到有消息进来或者超时。
这种方式的好处立刻就显现出来了:消息是持久化的,因为消息被存在了Redis的列表里,只要Redis不重启(或者配置了持久化即使重启也没事),消息就会一直待在那里,即使没有消费者,或者消费者宕机了,生产者照样可以不停地往队列里塞任务,等消费者恢复后,可以继续从队列里取消息处理,不会丢活,这就实现了所谓的“异步处理”,比如有一个发送邮件的任务,Web服务器收到请求后,不用自己吭哧吭哧去发邮件,它只需要把收件人、标题等内容作为一个消息 LPUSH 到名为 send_email_queue 的队列里,然后就立刻给用户响应,后台有一个专门的邮件发送服务,用 BRPOP 从这个队列里取任务,慢慢发,这样网站响应就快了,而且即使邮件服务暂时挂了,发送请求也不会丢,都在队列里存着呢。
用Redis列表做队列也有个小缺点,就是它不像专业队列那样支持“消息确认”(Acknowledgement),如果消费者从队列里取走了一个消息,正在处理的时候突然崩溃了,那这个消息就永远丢失了,因为队列里已经没了,为了解决这个问题,Redis后来还提供了更强大的 Stream 数据结构(根据Redis 5.0版本引入Stream的官方公告),它支持消息持久化、消费者组,还有类似Kafka的消息确认机制,能实现更可靠的消息传递,功能更强大了,但用法也相对复杂一些。
所以你看,Redis做消息中间件,就像它的名字一样,体现了“简单就是美”的哲学,Pub/Sub适合轻量级的实时广播,List队列适合简单的异步任务和解耦,虽然它在超大规模、超高并发的场景下可能比不上专业的Kafka,或者在高可靠要求下不如RabbitMQ功能丰富,但对于很多中小型项目、或者作为微服务架构中的轻量级通信工具来说,Redis提供的消息队列功能已经非常够用且高效了,避免了引入额外中间件的运维成本,这也是它“挺有意思”的地方所在。
本文由畅苗于2026-01-17发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/82553.html
