Connection reset 是连接建立后被服务端主动RST强制关闭,非网络连不上;90%以上源于Redis空闲超时、ACL变更未重认证、容器/Pod重建、云SLB静默断连或防火墙中断。

Connection reset 不是 Redis 拒绝连接,而是连接建立后被中途强制关闭,90% 以上是服务端主动断连,不是客户端配错了。
Connection reset 的真实含义和常见触发点
这个错误不是“连不上”,而是“连上了,但用着用着被踢了”。关键看日志里是否伴随 java.io.IOException: Connection reset by peer 或 Lettuce 报的 io.lettuce.core.RedisException: Connection closed。它和 Connection refused 完全不同:Connection refused 是 Redis 进程没监听或端口不对;Connection reset 是连接已建好、命令都发过去了,结果服务端突然把 TCP 连接 RST 掉。
常见触发点包括:
- Redis 主动 kill 掉空闲连接(
timeout配置生效) - Redis 6+ ACL 用户权限变更后未重认证,Lettuce 复用旧连接导致被断
- Docker 容器重启、K8s Pod 重建,但客户端没感知,还在往旧 IP 发包
- 云厂商 SLB/ALB 在连接空闲超时后静默断连(如阿里云默认 60 秒)
- 防火墙或中间设备(如某些企业级路由器)对长连接做异常中断
验证是否是服务端主动断连:用 redis-cli + client list
别急着改 Spring Boot 配置,先确认是不是 Redis 在“动手”。在 Redis 服务端执行:
redis-cli -h <host> -p <port> -a <password> client list</password></port></host>
观察输出中每个连接的 idle 字段(单位秒)。如果大量连接 idle 值接近你配置的 timeout(比如设了 30,看到一堆 28–30),基本就是 Redis 自己清理的。再检查 Redis 配置:
-
timeout:默认 0(永不过期),若设为非 0,就可能触发断连 -
tcp-keepalive:设为 0 表示不发保活包,NAT 设备容易丢连接 -
maxclients被打满后新连接会被拒绝,但已有连接也可能被挤掉
临时验证可执行 config set timeout 0,再试客户端调用——如果不再报 Connection reset,根因就锁定了。
Lettuce 连接池对 Connection reset 的响应缺陷
Lettuce 默认复用连接,且连接断开后不会自动重认证。一旦 Redis 因 ACL 变更或密码更新而要求重新 AUTH,Lettuce 会尝试复用旧连接发命令,结果收到 NOAUTH Authentication required,紧接着就是 Connection reset。
解决方法是显式启用自动重连与重认证:
LettuceClientConfiguration.builder()
.commandTimeout(Duration.ofSeconds(3))
.shutdownTimeout(Duration.ofMillis(100))
.useSsl() // 如需 TLS
.build();
更重要的是,在 RedisStandaloneConfiguration 中确保密码被正确传递,并启用 clientOptions:
- 加
.option(ClientOptions.builder().autoReconnect(true).pingBeforeActivateConnection(true).build()) - 避免使用
setPassword()单独设密码,改用RedisURI.create("redis://:pwd@host:6379/0")构造,保证认证信息随连接生命周期绑定
否则即使配置了密码,Lettuce 在重连时也可能漏掉 AUTH 步骤。
云环境和 Docker 下最容易忽略的网络层断连
本地跑得好,一上云就 Connection reset?重点查三层:
- 云服务器安全组 / 防火墙是否开启「连接跟踪老化时间」(如腾讯云默认 UDP 30s、TCP 900s,但部分场景会提前清表)
- Docker 网络模式:用
host模式或显式--network=container:redis,避免 bridge 模式下 NAT 层二次超时 - K8s Service 类型:NodePort 或 LoadBalancer 后面挂了云 LB,必须确认其空闲超时设置(通常远小于 Redis 的
timeout)
一个快速验证法:在应用容器内执行 telnet redis-host 6379,连上后不输命令,等 60 秒——如果此时 telnet 自动断开,说明中间链路有设备在主动 Kill 连接,和 Spring Boot 无关。
真正难缠的点在于:它不报错在启动时,也不总在高并发时,而是在连接空闲几十秒后第一次发命令时才崩。这种延迟性让很多人误判为“缓存注解没生效”或“RedisTemplate 初始化失败”,其实只是连接池里的某个连接被悄无声息地回收了。











