TCP 连接状态排查:TIME_WAIT、SYN_RECV 与端口耗尽

通过连接状态、监听队列和临时端口范围定位 TCP 建连失败,避免用错误的内核参数掩盖问题。

文章目录 · 4 节

连接超时不一定是网络丢包。服务端监听队列溢出、客户端临时端口耗尽和连接泄漏,都可能导致相同现象。

统计状态分布

ss -s
ss -ant | awk 'NR>1 {count[$1]++} END {for (s in count) print s, count[s]}'
ss -lntp

大量 SYN_RECV 表示握手没有完成,检查上游重试、SYN backlog 和防火墙;大量 CLOSE_WAIT 通常是应用没有关闭已被对端关闭的连接;TIME_WAIT 多并不天然异常,要结合新建连接速率判断。

检查端口与队列

sysctl net.ipv4.ip_local_port_range
sysctl net.core.somaxconn
netstat -s | grep -iE 'listen|overflow|drop'

客户端访问同一目标四元组时,可用临时端口是有限的。优先启用连接池、复用长连接和限制无界重试,不要直接缩短 TIME_WAIT 作为第一选择。

抓取握手证据

sudo tcpdump -nn -i any 'tcp[tcpflags] & (tcp-syn|tcp-fin|tcp-rst) != 0'

确认 SYN 是否发出、SYN-ACK 是否返回、谁发送 RST。抓包时间要短并限制过滤条件,避免给故障主机增加额外压力。

处理原则

先修复连接生命周期和重试策略,再调整内核队列。参数调优必须记录变更前后的建连失败率和队列溢出计数。