Java中Redis Pub/Sub适用于实时通知场景,核心是发即达、收即处理,适合订单提醒等允许少量丢失的场景;订阅端需实现MessageListener并注册为非lazy Bean,支持频道和通配符订阅;发布端用convertAndSend发送,消息无持久化与确认机制。

Java 中用 Redis 的 Pub/Sub 实现轻量级消息通知,核心是“发即达、收即处理”,不依赖持久化和确认机制,适合订单提醒、配置热更新、状态广播这类实时性高、允许少量丢失的场景。
订阅端:监听频道并处理消息
需要一个监听器接收消息,并注册到 Spring 容器中持续运行:
- 实现 MessageListener 接口,在
onMessage方法里解析频道名和消息体,例如:
String channel = new String(message.getChannel());<br> String content = new String(message.getBody());
- 用 RedisMessageListenerContainer 管理监听生命周期,必须设为
@Bean且非 lazy 初始化,否则启动后收不到消息 - 支持两种订阅方式:
✓addMessageListener(listener, new ChannelTopic("notify:order"))—— 监听指定频道
✓addMessageListener(listener, new PatternTopic("notify:*"))—— 通配符匹配,适合按前缀分类的通知
发布端:一行代码触发通知
使用 StringRedisTemplate 的 convertAndSend 即可发布:
- 示例:
stringRedisTemplate.convertAndSend("notify:user:login", "USER_8899_LOGGED_IN"); - 返回值是当前在线订阅者数量,不是发送成功与否的保证——无人在线时消息直接丢弃
- 消息内容建议结构化(如 JSON),包含业务标识、时间戳或版本号,便于订阅方做幂等或顺序判断
关键注意事项
Pub/Sub 看似简单,但几个细节容易导致收不到消息或行为异常:
立即学习“Java免费学习笔记(深入)”;
- 监听容器必须随应用启动就运行,不能在某个方法里临时创建再 start;推荐在配置类中声明为 Bean
-
onMessage是异步回调,不要在里面做 HTTP 调用、数据库写入等耗时操作,应交给线程池或响应式流处理 - 多个服务实例会各自收到同一消息(广播语义),如需单次消费,得上消息队列(如 Redis Stream)而非 Pub/Sub
- 无重试、无持久化、无消费确认,适合“通知型”而非“任务型”场景;重要逻辑建议叠加一次 Redis GET 校验兜底
适用与不适用边界
明确它能做什么、不能做什么,才能用得安心:
- ✅ 适合:
• 用户登录/登出广播
• 订单创建成功后触发短信或 WebSocket 推送
• 配置变更的秒级热同步(配合版本号校验)
• 微服务间轻量事件通知(如“库存扣减完成”) - ❌ 不适合:
• 需要 100% 投递保障的业务指令(如支付结果通知)
• 消息积压、延迟消费、重试补偿等复杂需求
• 大流量下要求严格顺序的场景(Pub/Sub 不保证多订阅者间的消息顺序)


















