ss 显示大量 TIME_WAIT,客户端偶发 Cannot assign requested address 或 conntrack 表压力。
高 QPS 短连接服务出现连接失败、超时或端口耗尽告警;ss -s 和 ss -tan state time-wait 显示大量 TIME_WAIT。服务端本身可能正常,问题集中在上游主动关闭连接的一方。
先确认 TIME_WAIT 在哪一侧、哪个端口,再看临时端口和 conntrack:
ss -tan state time-wait | wc -l
ss -tan state time-wait | awk '{print $4}' | sed 's/.*://' | sort | uniq -c | sort -nr | head
ss -tan state time-wait '( sport = :8080 )' | head
cat /proc/sys/net/ipv4/ip_local_port_range
sysctl net.ipv4.tcp_tw_reuse net.ipv4.tcp_max_tw_buckets net.ipv4.tcp_fin_timeout
ss -s
cat /proc/net/sockstat
连接表与错误日志:
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max
dmesg | grep -i 'conntrack.*table full'
grep -R 'Cannot assign requested address' /var/log/ 2>/dev/null | tail
netstat -s | grep -iE 'time wait|overflow'
TIME_WAIT 出现在哪一端,说明哪一端先发送了第一个 FIN。要确认关闭方向,可用抓包看 FIN:
tcpdump -i any -nn 'tcp port 8080 and (tcp[tcpflags] & (tcp-fin|tcp-rst) != 0)'
易误判:TIME_WAIT 是正常的连接状态(Linux 固定约 60 秒,即 2×MSL),数量高本身不是故障;真正的信号是 Cannot assign requested address、conntrack 满或四元组冲突。tcp_fin_timeout 不影响 TIME_WAIT(它控制 FIN_WAIT_2),改它不会减少 TIME_WAIT。tcp_tw_recycle 在 Linux 4.12 已移除,且在 NAT 环境下有害,禁止使用。
Connection: close、keepalive 关闭、HTTP/1.0),TIME_WAIT 落在服务端。tcp_max_tw_buckets 太小触发溢出,内核提前清理 TIME_WAIT。tcp_tw_recycle,NAT 后客户端连接随机失败。ip_local_port_range(如 10240 65000),增加可用端口。net.ipv4.tcp_tw_reuse=1(需启用 timestamps),仅影响主动发起的新连接。tcp_tw_recycle;不要指望 tcp_fin_timeout 缩短 TIME_WAIT。nf_conntrack_max,并谨慎调整 nf_conntrack_tcp_timeout_time_wait。Connection: close,检查 Nginx 与 upstream keepalive 配置。ss -s 的 timewait、临时端口使用率和 nf_conntrack_count/max,按速率告警。tcp_fin_timeout 能缩短 TIME_WAIT 吗?tcp_tw_reuse 能解决服务端 TIME_WAIT 过多的问题吗?tcp_fin_timeout 控制 FIN_WAIT_2,TIME_WAIT 时长由内核固定。tcp_tw_reuse 只对主动发起连接的一方生效,不解决服务端被动关闭产生的 TIME_WAIT。