用 ss 命令查看 TCP 连接状态:ss -tn 列出非监听连接,ss -tln 查看监听端口,ss -tan state time-wait | wc -l 统计 TIME-WAIT 数量;TIME-WAIT 过多需结合应用行为分析,ESTABLISHED 突增应排查连接泄漏或网络中断,SYN-RECEIVED/FIN-WAIT-2 堆积反映收发不一致,须配合 ss -tni 查重传与 RTO 综合判断。

怎么看当前 TCP 连接状态?
直接用 ss,别用过时的 netstat。后者依赖 /proc/net/tcp 解析,慢且不准;ss 从内核 socket 子系统直接读取,快、准、支持过滤。
-
ss -tn:列出所有 TCP 连接(不含监听端口) -
ss -tln:只看监听中的端口(-l表示 listening,-n禁用域名解析) -
ss -tan state time-wait | wc -l:统计 TIME-WAIT 连接数 - 加
-o可看连接超时时间,加-i可看重传、RTT 等底层指标
TIME-WAIT 太多是不是有问题?
不一定。Linux 默认保持 TIME-WAIT 状态 60 秒(2×MSL),这是协议要求,防止旧包干扰新连接。但若 ss -tan state time-wait | wc -l 持续 >5000,就得查原因。
- 常见诱因:
client主动断连频繁(如短连接 HTTP 调用未复用)、后端服务关闭连接太急(没等 client 发 FIN)、负载均衡器配置了不合理的健康检查频率 - 临时缓解可调
/proc/sys/net/ipv4/tcp_tw_reuse(设为 1),允许把处于 TIME-WAIT 的端口用于新 outbound 连接——但仅对 client 场景有效,server 不适用 - 真正根治要改应用行为:启用 HTTP Keep-Alive、用连接池、避免每请求都
close()
ESTABLISHED 连接数突增但业务没涨?
大概率是连接泄漏或半开连接堆积。先确认是否真 ESTABLISHED:ss -tn state established | head -20 看源/目标 IP 和端口分布。
- 如果大量连接来自同一 client IP + 不同源端口 → 可能是该 client 没正确 close,或网络中间设备(如防火墙)悄悄中断了连接,但 server 还在等数据
- 如果连接集中在某几个 server 端口 → 检查对应进程是否卡住(
strace -p $(pidof your_app)看是否阻塞在recv()或accept()) - 用
ss -tni查看每个连接的retrans(重传次数)和rto(超时时间):若retrans> 3,说明链路丢包或对端响应慢
为什么连接卡在 SYN-RECEIVED 或 FIN-WAIT-2?
这两个状态暴露的是两端行为不一致问题,不是单纯“连不上”。
-
SYN-RECEIVED堆积:server 收到 SYN,发了 SYN+ACK,但没收到 client 的 ACK。常见于 client 网络不可达、防火墙拦截了 ACK、或 client 发送窗口满导致 ACK 延迟 -
FIN-WAIT-2长期存在:server 发了 FIN,client 回了 ACK,但 client 没发自己的 FIN。本质是 client 应用没调用close()或崩溃后未清理 socket —— 此时 server 会等/proc/sys/net/ipv4/tcp_fin_timeout(默认 60 秒)后强制关闭 - 注意:
FIN-WAIT-2在无SO_LINGER设置时不会自动转 CLOSE,得靠 timeout;而CLOSE-WAIT堆积才是 server 自身没调close()的铁证
ss -tn state fin-wait-2 | awk '{print $5}' | sort | uniq -c | sort -nr | head -5
这条命令能快速定位哪类 client 最容易卡在 FIN-WAIT-2,方便针对性排查客户端逻辑或网络策略。
状态本身没“好坏”,关键看持续时间和上下文。盯着一个状态猛查不如结合 ss -tni 的重传、RTO、queue size 一起看——TCP 状态只是表象,背后永远是收发行为、超时设置、网络质量三者在博弈。










