要查看 CLOSE_WAIT 连接,本质是查已收 FIN 但未调用 close() 的半关闭连接;需用 ss -tan state close-wait 快速列出,结合 -p 或 lsof 定位进程,统计数量并观察是否长期堆积以判断是否僵死。

要查看处于 CLOSE_WAIT 状态的连接,本质是查“已收到对方 FIN、但本端还没调用 close() 关闭”的半关闭连接。这类连接不会自动消失,必须由应用主动释放,否则会堆积成僵死连接,耗尽文件描述符。
快速列出所有 CLOSE_WAIT 连接
使用 ss(推荐,比 netstat 更快更准确):
-
ss -tan state close-wait—— 显示所有 IPv4 的 CLOSE_WAIT 连接,含地址和端口 -
ss -tun state close-wait—— 加-u同时看 UDP(实际 UDP 无 CLOSE_WAIT,此参数可忽略)
若仍需用 netstat(部分旧系统):
netstat -ant | grep CLOSE_WAIT- 加
-p显示进程(需 root 权限):netstat -antp | grep CLOSE_WAIT
定位关联进程和端口
CLOSE_WAIT 本身不体现归属进程,需结合 -p 或后续过滤:
- 查指定端口(如 8080)上的 CLOSE_WAIT:
ss -tan state close-wait dport = :8080 - 查某进程(如 nginx)打开的 CLOSE_WAIT:
lsof -i -n -P -c nginx | grep CLOSE_WAIT - 提取进程 PID:
ss -tanp state close-wait | grep -o 'pid=[0-9]*' | cut -d= -f2 | sort -u
判断是否真“僵死”
单看状态不够,要确认是否长期未释放:
- 统计数量:
ss -tan state close-wait | wc -l,持续 >100 且缓慢增长需警惕 - 观察时间维度:CLOSE_WAIT 没有内核超时机制(不像 TIME_WAIT 可设
tcp_fin_timeout),只要进程不 close,它就一直挂着 - 对比正常业务量:若某接口调用量突增后 CLOSE_WAIT 大量堆积,大概率是该服务代码漏关连接
不是“查看完就结束”,而是为下一步做准备
看到 CLOSE_WAIT,目标不是“数出来”,而是“找到谁在扛着不放”:
- 拿到 PID 后,用
ps -p [PID] -o pid,ppid,comm,args看进程详情 - 用
lsof -p [PID]查该进程所有打开的 socket,确认哪些是 CLOSE_WAIT - 结合日志或代码检查:是否在异常分支、超时处理、finally 块中遗漏了
close()或socket.shutdown()

















