ss命令查看time_wait套接字详情需用ss -tan state time-wait,可显示每个连接的四元组、uid、inode等;加-p需root权限但对time_wait无效;/proc/net/sockstat中tw字段反映总量,需结合业务判断是否异常。

ss 命令怎么看 TIME_WAIT 套接字详情
Linux 中真正能查到「具体等待详情」的,只有 ss,不是 netstat。因为 netstat 只统计数量,而 ss 能列出每个处于 TIME_WAIT 状态的套接字四元组(源IP:端口 → 目标IP:端口)、UID、inode 和创建时间(需内核支持)。
执行以下命令可看到完整等待详情:
ss -tan state time-wait
关键点:
-
-t:只看 TCP(TIME_WAIT是 TCP 独有状态) -
-a:必须加,否则state time-wait过滤无效 -
-n:禁用 DNS 解析,避免卡顿和乱码 -
state time-wait:这是ss的内置状态过滤语法,不是 grep
如果还想看到归属进程(比如确认是不是某个服务残留的连接),得加 -p,但需要 root 权限:
sudo ss -tanp state time-wait
注意:-p 在 TIME_WAIT 套接字上通常显示 users:(("?",pid=0,fd=0)),因为连接已关闭,进程不再持有该 socket,所以别指望靠它定位“谁留下的”——它只对 ESTAB 或 LISTEN 有效。
/proc/net/sockstat 里怎么看等待总量
/proc/net/sockstat 不提供单个套接字详情,但它能告诉你当前系统级的等待压力是否异常。重点关注这一行:
cat /proc/net/sockstat | grep "TCP: tw"
输出类似:TCP: inuse 127 orphan 0 tw 489 alloc 135 mem 12
其中 tw 就是当前所有 TIME_WAIT 套接字总数。这个数本身不说明问题,要结合业务流量看:
- 短连接密集的服务(如 HTTP API 网关),
tw数千是正常的 - 如果
tw持续 > 65535,且alloc接近或超过net.ipv4.ip_local_port_range上限,说明端口耗尽风险高 -
orphan非零且持续增长,才是真问题——表示连接被内核回收但未被进程释放,可能有 socket 泄漏
为什么 lsof -i 不能替代 ss 查等待详情
lsof -i 默认不显示 TIME_WAIT 套接字,除非显式加 +E(启用扩展网络信息)且配合状态过滤:
lsof -i -n -P -sTCP:TIME_WAIT
但实际中会遇到几个硬限制:
- 普通用户执行时,大量
TIME_WAIT条目权限不足,显示为(deleted)或直接跳过 - 输出不含 inode、接收队列长度、发送队列长度等底层字段,无法判断是否堆积在缓冲区
- 性能差:扫描全量文件描述符比
ss直接读取内核 socket 表慢一个数量级
所以,查等待详情,ss 是唯一靠谱的选择;lsof 更适合查「哪个进程还开着某个端口」这类活。
排查时容易忽略的两个细节
一是 ss -o(显示计时器)在 TIME_WAIT 上基本没用——它只对 ESTAB 显示重传定时器,TIME_WAIT 的 2MSL 计时器不暴露给用户空间。
二是别用 grep TIME_WAIT 去筛 ss -tan 输出,因为部分内核版本(如 5.15+)默认把状态缩写为 time-wait,大小写和连字符必须完全匹配,否则漏掉全部结果。
真正要盯住的,是 ss -tan state time-wait 的原始输出 + /proc/net/sockstat 的 tw 值联动看——前者看分布,后者看总量趋势。











