用Redis搞异步消息订阅,处理起来其实没那么复杂,也挺实用的
- 问答
- 2026-01-16 00:58:47
- 3
基于常见的Redis使用模式和实践经验总结)
用Redis搞异步消息订阅,处理起来其实没那么复杂,也挺实用的,很多人一听到“消息队列”、“发布订阅”这些词,就觉得是RabbitMQ、Kafka这些大家伙的专属领域,感觉门槛很高,配置起来也麻烦,其实对于很多不那么极端复杂的场景,用Redis就能轻松搞定,而且效果出奇的好。
核心思想就一句话:一个角色发消息(发布者),一个或多个角色收消息(订阅者),中间用Redis做个“大喇叭”或者“信箱”。
Redis主要提供了两种方式来做这个事,一种是“发布订阅”(Pub/Sub),另一种是用“列表”(List)结构模拟消息队列,两种方法各有各的用武之地。

先说第一种,Redis自带的Pub/Sub模式。
这个模式特别像我们生活中的电台广播,想象一下:
- 发布者(Publisher) 就像电台主持人,他不用关心谁在听,只需要对着麦克风(也就是Redis)说:“我现在要在FM101.1频道播报一条新闻了!”
- Redis 就是这个广播塔,负责把信号发出去。
- 订阅者(Subscriber) 就像我们听众,如果你想听新闻,你只需要提前把收音机调到FM101.1频道,然后等着就行了,一旦主持人说话,你就能实时听到。
在代码里就是这么简单,处理消息的服务(订阅者)启动的时候,就发一个命令给Redis:“我要订阅‘order_create’这个频道。”然后这个服务就会挂起连接,静静地等待,当下单服务(发布者)完成一个订单时,它只需要执行一个命令:“向‘order_create’频道发布一条消息,内容是订单ID123。”Redis一收到这条命令,会立刻把“订单ID123”这个消息推送给所有当前正在监听‘order_create’频道的订阅者。

这种模式的好处是快,因为是实时推送的,几乎没有延迟,非常适合做实时通知,比如在网页上实时显示在线人数、实时聊天室、服务器向客户端推送进度更新等。
但它也有个明显的“缺点”:它不持久化,还用电台来打比方,如果主持人广播的时候,你的收音机没开,或者信号不好,那这条新闻你就永远错过了,在系统里,如果订阅者服务当时刚好重启了,没在线,那么它就会错过那条消息,所以Pub/Sub适合那种“错过了也没关系”的实时场景。
那如果消息很重要,不能丢怎么办?这就轮到第二种方法上场了:用Redis的List结构模拟消息队列。

这个方法更像是一个“任务信箱”。
- 生产者(Producer) 负责产生任务,用户上传了一张图片需要压缩,生产者就把“压缩图片task_888”这个任务写在一张纸条上。
- Redis的List 就是这个信箱,生产者把纸条塞进信箱(也就是从列表的左边插入,命令叫
LPUSH)。 - 消费者(Consumer) 负责处理任务,它会不停地去检查信箱里有没有新纸条(从列表的右边取出任务,命令叫
RPOP),如果取到任务,就执行压缩图片的工作。
这个方法的关键在于,只要纸条没被取走,它就永远躺在信箱里,即使消费者服务宕机了一小时,重启之后,它依然可以去信箱里把积压的任务一个个取出来处理掉,这就保证了消息不会因为消费者不在线而丢失,实现了简单的“持久化”。
为了让消费者不用傻傻地不停去问“有信吗?有信吗?”,可以优化一下,使用BRPOP命令,这个命令的意思是:“阻塞式地等待并从右边取出消息,如果信箱是空的,我就在这儿等着,直到有信塞进来或者超时。”这样既避免了无用的循环查询消耗CPU,又能及时处理新任务。
这种List队列的方式,非常适合处理异步任务,比如发送邮件、处理视频转码、清理数据等耗时操作,用户点击“发送邮件”后,Web服务只需要花几毫秒把发邮件的任务丢到Redis队列里,就可以立刻返回响应告诉用户“请求已接收”,而真正耗时的发邮件工作,则由后台的消费者服务慢慢去处理,这样前后端就解耦了,网站的响应速度也快了。
所以你看,用Redis做异步消息处理,真的不复杂,你不需要去理解那些专业消息中间件里复杂的概念(比如Exchange、Partition、ACK机制等),Redis的几个基本命令就够用了,对于中小型项目、初创公司或者功能模块之间的解耦,它是一种非常轻量、高效且易于理解和维护的方案,如果您的业务量超级大,对消息的顺序、可靠性、吞吐量有极致的要求,那确实需要考虑专业的消息队列,但在那之前,Redis无疑是一个性价比极高的选择,非常实用。
本文由盈壮于2026-01-16发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://www.haoid.cn/wenda/81487.html
