<p>要分析 FIN-WAIT-2 连接耗时分布,必须使用 ss -ant o state fin-wait-2 获取计时器信息,其中 timer:(on,XXs,0) 的 XXs 是剩余超时时间,已存在时间 ≈ tcp_fin_timeout - XXs。</p>

要分析 FIN-WAIT-2 状态连接的耗时分布,仅靠 ss -ant 不够——它只显示状态和基础连接信息,不包含每个连接已存在多久。真正能获取“存活时长”的关键参数是 -o(显示计时器信息),配合状态过滤,才能估算 FIN-WAIT-2 连接的驻留时间。
✅ 正确命令:用 ss -ant o state fin-wait-2 查看带计时器的 FIN-WAIT-2 连接
ss -ant o state fin-wait-2
-
-o:显示 socket 的计时器(timer)字段,格式为timer:(<type>,<expire>,<retrans)
其中<expire>是距离该计时器触发剩余的秒数(单位:秒),对 FIN-WAIT-2 来说,这通常对应内核为该连接设置的tcp_fin_timeout倒计时。 -
state fin-wait-2:精准过滤,大小写不敏感(fin-wait-2、FIN_WAIT2、fin_wait2均可)
输出示例:
State Recv-Q Send-Q Local Address:Port Peer Address:Port Timer FIN-WAIT-2 0 0 10.0.1.10:8080 192.168.5.22:54321 timer:(on,28s,0) FIN-WAIT-2 0 0 10.0.1.10:8080 192.168.5.22:54322 timer:(on,5s,0) FIN-WAIT-2 0 0 10.0.1.10:8080 192.168.5.23:41001 timer:(on,57s,0)
⚠️ 注意:
timer:(on,XXs,0)中的XXs是剩余超时时间,不是已存在时间。所以“已存在时间 ≈ tcp_fin_timeout - XXs”。例如当前tcp_fin_timeout=60,某连接显示28s,说明它已在 FIN-WAIT-2 状态停留约 32 秒。
? 快速统计耗时分布(按“已存在秒数”分段)
假设 tcp_fin_timeout=60,可用以下命令粗略分组(需 root 或 CAP_NET_ADMIN):
ss -ant o state fin-wait-2 | \
awk '$1 ~ /FIN[-_]WAIT[-_]2/ && $7 ~ /timer\([^)]*on,\s*([0-9]+)s/ {
secs = 60 - int(substr($7, index($7,"on,")+3, index($7,"s")-index($7,"on,")-3))
if (secs < 10) a["<10s"]++
else if (secs < 30) a["10-29s"]++
else if (secs < 60) a["30-59s"]++
else a[">=60s"]++
}
END { for (i in a) print i ": " a[i] }'输出类似:
<10s: 12 10-29s: 87 30-59s: 215 >=60s: 0
这说明大部分 FIN-WAIT-2 连接已驻留 30 秒以上,接近超时阈值,提示对端长期未发 FIN —— 很可能客户端异常、网络中断或应用未 close。
? 补充定位:关联进程与连接来源
加 -p(需 root)可看到占用该 socket 的进程:
ss -antop state fin-wait-2 | head -10
重点关注:
-
PID和Program列,确认是否来自预期服务(如 nginx、java) - 源 IP(
Peer Address:Port)是否集中于某几台客户端(如移动 APP、IoT 设备),便于协同排查终端行为
? 关键前提确认
执行前请先检查实际生效的超时值:
cat /proc/sys/net/ipv4/tcp_fin_timeout
若返回 60,则上述计算以 60 为基准;若已调为 30,请把脚本中 60 替换为 30。
? 提示:
timer字段只对内核启用 FIN-WAIT-2 超时的连接有效。若连接被用户进程持有(如设置了SO_LINGER且 linger=0)、或内核版本较老(< 2.6.17),可能显示timer:(off,0ms,0),这类连接不会自动释放,必须从应用层修复。
不复杂但容易忽略:-o 是打开耗时分析的钥匙,没它就只能数数量,无法看分布。


















