redis pub/sub连接超时断开主因是空闲长连接被静默关闭,需服务端tcp-keepalive≥60与timeout=600协同配置,客户端配心跳(lettuce/redisson/jedis各异)及dns与节点状态校验,三者缺一不可。

Redis Pub/Sub 连接超时断开,不是订阅逻辑出错,而是 TCP 长连接在空闲时被服务端、中间网络设备或客户端自身静默关闭。光靠重连不治本,必须从 tcp-keepalive、timeout、客户端心跳三端协同配置。
Redis 服务端必须配 tcp-keepalive 和 timeout
默认 tcp-keepalive 0 表示禁用内核保活探测,timeout 300 会让空闲 5 分钟的订阅连接被直接踢掉——而 Pub/Sub 本来就不发命令,纯等消息,必然中招。
-
config set tcp-keepalive 60:启用 TCP 层保活,每 60 秒发一次 ACK 探测,能快速发现 NAT/防火墙/云 LB 的静默断连 -
config set timeout 600:把服务端空闲断连阈值拉到 10 分钟,给客户端留出心跳与重连窗口 - 这两项必须写入
redis.conf并执行CONFIG REWRITE或重启生效,否则重启即丢
客户端不能只依赖 autoReconnect=true
Lettuce、Redisson 等客户端设了 autoReconnect=true,但若没配心跳,连接已僵死却迟迟不触发重连;Jedis 甚至默认不带心跳能力。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- Lettuce:需显式开启
ClientOptions.builder().pingBeforeActivateConnection(true),且该配置仅对普通命令连接生效;StatefulRedisPubSubConnection要单独监听onException后手动调connection.ping() - Redisson:必须设
setHeartbeatInterval(15000)(15 秒),并确保setSubscriptionConnectionPoolSize(20),避免单连接排队阻塞 - Jedis:得在订阅线程里自己起定时器,定期调
jedis.ping(),且必须发生在PubSub所用的那个Jedis实例上,不能混用连接池里的其他连接
别忽略 DNS 缓存和 VIP 漂移导致的“假连接”
客户端连的是域名(如 redis-prod.cluster.example.com),DNS 缓存过久或云 Redis VIP 漂移后,旧连接可能还连着下线节点,PING 成功但 PUBLISH 失败,错误表现为 READONLY You can't write against a read only replica 或无响应。
- JVM 启动加
-Dsun.net.inetaddr.ttl=60,强制 DNS 缓存 60 秒刷新 - Redisson 用户检查
dnsMonitoringInterval,建议保持默认 5000ms 或调至 3000ms - 所有客户端应定期执行
INFO replication或CLUSTER NODES校验当前连接是否仍指向有效 master 节点
真正稳定的 Pub/Sub 不是靠“不断重连”,而是让连接在空闲时持续被探测、被确认、被刷新。服务端 tcp-keepalive 是底线,客户端心跳是保险,DNS 与节点状态校验才是兜底——三者缺一,都可能在凌晨三点悄无声息地丢消息。










