被动等待关闭怎么定位
被动等待关闭状态表示对端已经发来关闭报文、本端协议栈也确认了,但应用进程始终没有调用关闭。它是所有连接状态里指向最明确的一个:数量只要持续增长,几乎可以确定应用侧存在资源泄漏——连接池未归还、异常分支漏关、缺少超时机制。它与回收态的区别值得强调:回收态是主动关闭方的正常状态,会自己消失;被动等待关闭是没人收拾的残局,只能等应用关闭连接或进程退出才回收。
基本信息
| 适用平台 | Linux,用 iproute2 的连接工具查看,带进程信息需要权限 |
|---|---|
| 状态含义 | 对端已发关闭报文并被我方确认,本端应用未调用关闭 |
| 判据 | 数量持续增长且与请求量同步,重启应用后归零 |
| 常见根因 | 应用未关闭连接、连接池泄漏、异常分支漏关、缺超时 |
| 耗时特征 | 通常不会自行消失,只有应用关闭连接或进程退出才回收 |
| 处置方向 | 修复代码与连接池,补超时、健康检查与句柄监控 |
典型使用场景
- 服务间歇性无响应并伴随句柄告警:先确认该状态是否堆积
- 压测后句柄数与连接数只增不减,用状态视图定位泄漏方向
- 排查连接池配置:池上限与借出未归还的组合最容易造成泄漏
- 区分归属:按进程聚合确定是哪个服务在漏,避免全员排查
- 验证修复:重启后归零,再跑一轮压测看是否重新增长
- 容量与风险排期:按泄漏速率换算句柄耗尽时间点,据此安排修复窗口
定位与归属
定位与归属
ss -Htan state close-wait | wc -l # 总量
ss -tanp state close-wait | head -30 # 带进程信息看归属(需要权限)
ls /proc/<PID>/fd | wc -l # 该进程持有的文件描述符数量
lsof -p <PID> | grep -c socket # 其中套接字数量
cat /proc/<PID>/limits | grep -i 'open files' # 句柄上限
watch -n 5 'ss -Htan state close-wait | wc -l' # 观察是否单向增长
systemctl restart <服务> # 重启后归零可确认归属该进程
ss -Htan state close-wait | wc -l # 复测:归零即印证泄漏来源判据与处置动作
| 判据 | 含义 | 动作 |
|---|---|---|
| 数量恒定在低位 | 稳态下的少量正常状态 | 记录基线即可,不做处理 |
| 数量持续增长 | 应用未关闭连接 | 按进程聚合定位到具体服务 |
| 与请求量同步上升 | 几乎每个请求都漏一个连接 | 检查异常分支与连接池归还逻辑 |
| 重启后归零 | 可确认泄漏归属该进程 | 进入代码级修复并补超时 |
| 句柄数接近上限 | 即将无法建立新连接 | 临时扩容上限并尽快修代码 |
| 数量与重启时间同步下降 | 重启只是临时缓解 | 把它当临时手段,尽快定位代码路径 |
内核无法替应用关闭这类连接,主动权在应用进程;网络相关的内核参数再怎么调都不会让它消失。把它当内核问题处理,除了浪费时间,还会掩盖真正的泄漏点。
排查顺序建议先按进程聚合、再查句柄:进程级聚合能一次排除无关服务;进程的文件描述符目录与句柄查看工具的结果可以进一步区分是套接字泄漏还是普通文件泄漏。把计数写进监控做成曲线,比单点数值更能说明泄漏速率。