redis pub/sub仅适用于“丢了也无妨”的轻量级通知场景,如缓存失效广播、服务健康心跳、实时日志分发、前端页面状态刷新指令;不适用于需可靠投递的业务,如订单支付结果或资金流水确认。

能用,但必须清楚它不保证消息可靠送达——订阅者离线、网络中断、进程崩溃时,消息直接丢失。
Redis Pub/Sub 适合什么场景?
只适用于“丢了也无妨”的轻量级通知,比如:缓存失效广播、服务健康心跳、实时日志分发、前端页面状态刷新指令。不适合订单支付结果、资金流水确认这类必须送达的业务。
- 发布者调用
PUBLISH后立即返回,不等订阅者响应 - 订阅者必须在线才能收消息;断连重连后,断连期间的消息全部丢弃
- 没有 ACK 机制,无法知道谁收到了、谁没收到、谁处理失败了
- 频道(
channel)名是字符串,不支持通配符以外的动态路由(PSUBSCRIBE channel.*可用,但匹配逻辑简单)
Spring Boot 中如何注册监听器?
别直接 new MessageListenerAdapter,得让 Spring 管理生命周期,否则容器销毁时监听器可能还在跑,导致重复消费或 NPE。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 监听器类加
@Component,确保被 Spring 扫描到 - 在配置类里声明
RedisMessageListenerContainerBean,并注入连接工厂 - 用
container.addMessageListener(listener, new ChannelTopic("order.result"))注册,不是手动调用subscribe() - 注意:一个
RedisMessageListenerContainer实例可管理多个监听器,但不要为每个频道起一个新 container
为什么不能拿它当任务队列用?
因为 PUB/SUB 和 LPUSH/BRPOP 是两套完全不同的底层机制:前者靠内存中的订阅字典广播,后者靠阻塞式列表读取。混用会导致语义混乱和资源浪费。
- 用
PUBLISH发送“任务” → 订阅者收到后立刻执行 → 若执行失败,无重试、无持久化、无顺序保障 - 真正要异步执行任务,该用
List+BRPOP或Stream(Redis 5.0+),它们支持 ack、pending list、group 消费 - 常见错误:把订单创建事件用
PUBLISH order.created推出去,然后监听器去扣库存——一旦监听器挂掉,库存就永远不扣
生产环境必须检查的三个配置点
缺一不可,否则监听器根本收不到消息。
-
redis.conf中确认notify-keyspace-events是空值(Pub/Sub 不依赖它),别误开Ex——那是键过期事件,和频道无关 - Spring 的
RedisConnectionFactory必须启用use-pool=true(默认开启),否则单连接无法同时支撑发布+订阅 - 监听器的
onMessage方法里,反序列化要用和发送端一致的RedisTemplate序列化器,比如都用StringRedisTemplate,否则message.getBody()解出来是乱码或 null
真正关键的不是怎么写监听器,而是想清楚:这个通知丢了,业务是否还能自愈?如果不能,就别用 Pub/Sub。










