首页/网络/网络排障速查/CLOSE-WAIT 泄漏定位

CLOSE-WAIT 泄漏定位

CLOSE-WAIT 表示对端已发 FIN、本端应用没有 close():数量持续增长是典型的资源泄漏信号(连接池未归还、代码漏关、无超时),调内核参数无效。

网络排障速查网络更新于 2026-10-13

被动等待关闭怎么定位

被动等待关闭状态表示对端已经发来关闭报文、本端协议栈也确认了,但应用进程始终没有调用关闭。它是所有连接状态里指向最明确的一个:数量只要持续增长,几乎可以确定应用侧存在资源泄漏——连接池未归还、异常分支漏关、缺少超时机制。它与回收态的区别值得强调:回收态是主动关闭方的正常状态,会自己消失;被动等待关闭是没人收拾的残局,只能等应用关闭连接或进程退出才回收。

基本信息

适用平台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            # 复测:归零即印证泄漏来源

判据与处置动作

判据含义动作
数量恒定在低位稳态下的少量正常状态记录基线即可,不做处理
数量持续增长应用未关闭连接按进程聚合定位到具体服务
与请求量同步上升几乎每个请求都漏一个连接检查异常分支与连接池归还逻辑
重启后归零可确认泄漏归属该进程进入代码级修复并补超时
句柄数接近上限即将无法建立新连接临时扩容上限并尽快修代码
数量与重启时间同步下降重启只是临时缓解把它当临时手段,尽快定位代码路径
内核无法替应用关闭这类连接,主动权在应用进程;网络相关的内核参数再怎么调都不会让它消失。把它当内核问题处理,除了浪费时间,还会掩盖真正的泄漏点。
排查顺序建议先按进程聚合、再查句柄:进程级聚合能一次排除无关服务;进程的文件描述符目录与句柄查看工具的结果可以进一步区分是套接字泄漏还是普通文件泄漏。把计数写进监控做成曲线,比单点数值更能说明泄漏速率。

易错点

  • 把该状态当内核问题去调参数,方向完全错误
  • 只看总数不看归属进程:多进程共用端口时先按进程聚合再定位
  • 只重启应用不修代码,同样条件出现后故障必然复发
  • 用放大会话数或句柄上限来缓解,掩盖泄漏本身,内存与句柄最终仍会被耗尽
  • 把定期重启当成长期方案,泄漏速率不变时故障仍会在重启窗口之间暴露

数据来源与参考

  • RFC 9293:CLOSE-WAIT 状态语义
  • man 8 ss

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌