LinuxTCP连接状态解析_网络异常定位方法【教程】

11次阅读

用 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 综合判断。

LinuxTCP连接状态解析_网络异常定位方法【教程】

怎么看当前 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 状态只是表象,背后永远是收发行为、超时设置、网络质量三者在博弈。

text=ZqhQzanResources