connected_clients持续上涨是redis连接泄露的最直接证据;需多次执行info clients观察趋势,结合client list查idle过大或来源集中的异常连接,并检查jedis是否漏close、lettuce是否误new客户端、线程是否阻塞在getresource。

看 connected_clients 是否持续上涨
这是最直接、最不可绕过的信号。Redis 服务端的 connected_clients 字段反映当前 ESTABLISHED 状态的客户端连接数,它不撒谎——只要这个值在业务无明显增长的情况下缓慢但稳定地上升(比如每小时+5、每天+100),基本就是泄露。
操作很简单:redis-cli -a your_password info clients,重点盯 connected_clients;隔 30–60 秒多跑几次,画个简易时间序列。别只采样一次,有些泄露在低峰期一天才涨几十,单次查看毫无异常。
- 若用的是 Jedis(非连接池托管场景),
connected_clients≈ 活跃连接数,上涨即危险 - 若用的是 Lettuce 或 Redisson,默认复用 Netty 连接,
connected_clients上涨说明连接没被回收,或连接池失效 - 注意排除干扰:主从切换、压测、网络抖动重连风暴会引发短时突增,需结合变更日志和业务时间点交叉判断
执行 CLIENT LIST 找“僵尸连接”
CLIENT LIST 能暴露每个连接的细节,是定位泄漏源头的关键命令。重点关注两个字段:
-
idle:该连接空闲秒数。值 > 3600(1 小时)且持续增长,大概率是借出去没还的连接 -
addr:客户端 IP:port。如果大量高idle连接都来自同一台应用机器,问题就锁定在那台服务上 - 顺手加个过滤:
redis-cli -a your_password client list | grep "idle=.*[3-9][0-9][0-9][0-9]",快速筛出可疑连接
注意:CLIENT LIST 输出量大,生产环境慎用高频轮询;可配合脚本定时采集关键字段,避免冲击 Redis 性能。
查应用进程的 TCP 连接状态
服务端 connected_clients 是结果,应用端的 TCP 连接才是第一现场。在疑似泄露的应用服务器上执行:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
netstat -an | grep :6379 | grep ESTABLISHED | wc -l
这个数字应该远小于 Redis 的 connected_clients(因一个应用进程可能建多个连接,但通常有上限)。如果它也持续增长,且与 connected_clients 趋势高度一致,说明泄漏确实发生在客户端代码层,而非网络中间件或代理。
- 更进一步,用
lsof -i :6379查看具体是哪个进程 PID 在持有哪些连接 - 若看到大量连接处于
CLOSE_WAIT状态,说明应用没主动发起 FIN,常见于未正确关闭 socket 的场景 - Java 应用可配合
jstack <pid></pid>搜getResource,看线程是否卡在获取连接上
Redis-py 和 Spring Boot 中容易被忽略的“假正常”
很多团队监控到 connected_clients 稳定,就以为没问题——其实只是泄漏还没爆发,或者被掩盖了。
-
redis-py 默认
max_connections是 2³¹−1,理论无上限,但 OS 层文件描述符早耗尽了;此时你会看到OSError: [Errno 24] Too many open files,而不是 Redis 报错 - Spring Boot + Lettuce 默认启用连接复用,
connected_clients不涨 ≠ 连接健康;得看连接池指标:lettuce.pool.active、lettuce.pool.idle,这些需通过 Micrometer 暴露并接入 Prometheus - ThinkPHP 或自研封装中,如果用
new \Redis()后只调connect()没配setOption(\Redis::OPT_READ_TIMEOUT, ...),连接可能卡死在 read 阶段,既不超时也不释放,connected_clients一直挂着
真正难缠的泄露,往往藏在超时设置不合理、异常分支漏归还、或健康检查被禁用这些细节里——它们不会立刻崩,但会让系统越来越脆。










