📚 实战篇 27. Redis 消息队列 - 基于 Pub/Sub 实现消息队列学习文档
一、 核心概念:什么是 Pub/Sub?
Pub/Sub 是 Publish(发布)和 Subscribe(订阅)的缩写。
它与 List 队列最大的不同在于:List 是一个真实的“容器”(数据存在链表里),而 Pub/Sub 并不是一种数据结构,它是一种消息路由机制。
通俗的比喻(收音机与广播电台):
- 频道 (Channel): 就像电台的频率(如 FM 90.0)。
- 消费者 (Subscriber): 就像拿着收音机的人,调到 FM 90.0 进行收听。可以有成千上万个人同时收听这一个频道。
- 生产者 (Publisher): 就像电台的主播,对着 FM 90.0 喊话。所有调到这个频道的收音机,都会同时收到这句话。
二、 核心命令与实操演示
在 Redis 中,操作 Pub/Sub 非常简单,主要有以下三个核心命令:
-
SUBSCRIBE channel [channel ...](精确订阅)- 作用: 消费者订阅一个或多个指定的频道。
- 演示: 开启一个 Redis 客户端,输入
SUBSCRIBE order.queue。此时该客户端会进入阻塞监听状态,等待消息到来。
-
PUBLISH channel message(发布消息)- 作用: 生产者向指定的频道发布一条消息。
- 演示: 开启另一个 Redis 客户端,输入
PUBLISH order.queue "order_id_1001"。 - 结果: 此时,所有执行了
SUBSCRIBE order.queue的客户端,都会立刻在屏幕上打印出"order_id_1001"这条消息。
-
PSUBSCRIBE pattern [pattern ...](模式/通配符订阅)- 作用: 订阅与指定模式匹配的所有频道(
*代表通配符)。 - 演示: 消费者执行
PSUBSCRIBE order.*。那么不论生产者向order.queue还是order.pay频道发送消息,这个消费者都能统统接收到!
- 作用: 订阅与指定模式匹配的所有频道(
三、 Pub/Sub 的优缺点剖析 (面试高频重点)
面试官经常会问:“既然 Pub/Sub 支持广播,那为什么现在的互联网大厂很少用它来做订单核心链路的消息队列?”
-
优点:
- 支持多消费者广播: 完美解决了上一节 List 队列“一条消息只能被消费一次”的痛点。
- 支持模式匹配订阅:
PSUBSCRIBE让消息的路由分发变得非常灵活。
-
致命缺点(为什么秒杀系统不用它):
- 缺乏持久化(阅后即焚): 这是它最大的硬伤!发送出去的消息,Redis 根本不会把它存在内存或磁盘里。如果发送消息时,没有任何消费者在线监听,这条消息就永远消失了,就如同电台广播,错过了就是错过了。
- 消息丢失风险极高: 哪怕消费者在线,如果网络突然抖动导致断开连接,在重连期间生产者发出的所有消息,消费者也全都会漏掉。
- 没有消息确认机制(ACK): 消费者收到消息后处理到一半报了异常,Redis 也不知道,无法重新投递。
- 消息堆积导致断开: 如果生产者发消息极快,消费者处理极慢,Redis 会为每个消费者分配一个缓冲区。当缓冲区被打满,Redis 会强行断开消费者的连接,导致后续数据全面丢失。
学习总结
Pub/Sub(发布订阅) 是 Redis 提供的一种轻量级消息分发机制。
它适合:对数据丢失不敏感的实时场景(例如:实时聊天室的群发、JVM 本地缓存的更新通知等)。
它绝对不适合:要求数据强一致性、绝对不能丢单的核心业务场景(例如:我们的优惠券秒杀订单)。