rpatterntopic漏收消息典型表现为高峰期或重启后部分匹配频道消息消失,根本原因在于订阅连接未自动重连、codec不匹配导致静默丢弃、集群模式下psubscribe未广播至全部master节点。

Redisson RPatternTopic 漏收消息的典型表现
不是完全收不到,而是某些匹配到的频道消息在高峰期或重启后突然消失;RPatternTopic 的 addListener 回调没触发,但用 redis-cli --csv psubscribe '__key*__:*' 能抓到原始 PubSub 流——说明 Redis 层消息是发出去了,问题出在 Redisson 客户端侧。
订阅连接未自动重连导致 pattern 订阅丢失
Redisson 默认的 PubSub 连接是「懒初始化 + 无心跳保活」的。当网络抖动、Redis 服务端主动断连(如超时踢出空闲连接)、或客户端 GC 导致线程暂停时,底层 Netty 连接可能静默断开,而 RPatternTopic 不会自动重建 pattern 订阅关系——它只在首次 addListener 时发一次 PSUBSCRIBE 命令。
- 检查日志里是否有
Connection closed by remote host或Channel inactive等 Netty 断连提示 - 确认
Config.useSingleServer()或useClusterServers()中是否设置了setPingConnectionInterval(30000)(推荐设为 30s) - 强制启用订阅连接保活:在配置中显式开启
setKeepAlive(true)和setTcpNoDelay(true)
pattern 订阅与消息解码器不兼容引发静默丢弃
Redisson 的 RPatternTopic 内部使用 PubSubPatternMessageDecoder 解析消息,但它对消息体格式极其敏感:如果发布方用 redisTemplate.convertAndSend(...) 发送字符串,而客户端配置了 JsonJacksonCodec,解码器会尝试把纯字符串反序列化为 JSON 对象,失败后直接跳过该消息,也不抛异常——这就是「偶发漏收」最隐蔽的原因。
- 统一消息格式:生产者和消费者必须共用同一套
Codec,且不能混用原生 Redis 命令(如redis-cli publish)和 Redisson API - 调试手段:临时将
config.setCodec(new StringCodec()),看漏收是否消失;若恢复,则证明是 codec 不匹配 - 避免跨框架混用:不要让 Spring Data Redis 的
RedisTemplate和 Redisson 的RPatternTopic共享同一类消息通道
集群模式下节点发现延迟导致 pattern 订阅不全
在 Redis 集群中,PSUBSCRIBE 必须发给所有主节点才能监听全量 keyspace 事件。Redisson 默认只向初始配置的节点发起订阅,若集群拓扑变更(如新增主节点),新节点上的 pattern 订阅不会自动同步。
- 确保
config.useClusterServers().setScanInterval(2000)已设置(2s 是合理下限,太长会导致拓扑感知滞后) - 检查
RTopic/RPatternTopic是否在集群所有 master 节点上都建立了连接:通过redis-cli -c -h node1 ping等方式验证节点可达性 - 关键补丁:升级到
redisson-spring-boot-starter 3.52.0+,该版本修复了集群模式下PSUBSCRIBE未广播到全部 master 的 bug
真正棘手的是「断连不报错 + 解码失败不告警」这两层静默机制叠加——它们让问题看起来像随机丢包,实际却是确定性缺陷。上线前务必用 redis-cli psubscribe 抓包比对,而不是只信日志里的 listener 回调。











