time_wait连接数多本身不是问题,真正要查的是是否引发“cannot assign requested address”或连接失败;需用ss -s对比ip_local_port_range判断端口是否耗尽,并结合错误日志、dmesg和ss -tan定位短连接源头,优先应用层复用连接而非盲目调参。

TIME_WAIT 连接数多本身不是问题,真正要查的是它是否导致了 Cannot assign requested address 或连接建立失败。
怎么看TIME_WAIT是不是真压垮了系统
别光数个数。先执行 ss -s,看输出里类似 timewait 42312 这一行,再对比 cat /proc/sys/net/ipv4/ip_local_port_range 的范围(比如默认 32768 60999,共约 28232 个端口)。如果前者长期 >25000 且伴随错误日志,才算危险。
- 查错误日志:
grep "Cannot assign requested address" /var/log/messages或应用日志里有没有connect: cannot assign requested address - 确认是否同步发生:用
dmesg | grep "time wait bucket"看有没有TCP: time wait bucket table overflow,有就说明内核已开始丢包 - 检查连接方向:运行
ss -tan state time-wait | head -10,看远端 IP 和端口是否集中在某几个服务——如果是,问题大概率在调用方,不是本机配置
怎么快速定位是哪个进程在狂建短连接
TIME_WAIT 多,八成是某个客户端进程在高频发起短连接。用 ss -tan state time-wait 结合 lsof 锁定源头:
Linux系统管理专家,覆盖12大模块:用户权限、SSH、存储、网络、systemd、防火墙、日志监控、备份恢复、TLS证书、Ansible、容器、IaC。提供配置、验证、加固、监控、备份、自动化、故障排查、回滚闭环。关键词:useradd、sudo、sshd_config、chmod、SEL...
- 先找可疑进程 PID:
pgrep -f "your-service-name" - 再查它开了多少 outbound 连接:
lsof -p <pid> -iTCP -n | grep '->' | wc -l</pid> - 重点看源端口是否在疯狂跳变(如
:42312、:42313…),这是典型短连接风暴特征 - 如果看到大量
ESTABLISHED但生命周期极短(几秒就变TIME_WAIT),基本可断定没复用连接
哪些内核参数改了有用,哪些纯属误导
很多教程乱推 tcp_fin_timeout,但它对 TIME_WAIT 时长完全无效——RFC 规定就是 2MSL(≈60 秒),Linux 不提供缩短接口。真正该动的只有这几个:
- 必须开:
net.ipv4.tcp_tw_reuse = 1(配合net.ipv4.tcp_timestamps = 1,现代内核默认开,但建议显式写死) - 推荐扩:
net.ipv4.ip_local_port_range = 1024 65535(释放全部非特权端口,注意防火墙策略是否允许低号端口) - 按需提:
net.ipv4.tcp_max_tw_buckets = 200000(避免桶满后内核静默丢包,值设太小反而更糟) - 必须关:
net.ipv4.tcp_tw_recycle = 0(NAT 环境下必出连接失败,4.12+ 内核已移除,旧配置残留得清)
为什么调参之后还是反复告警
因为内核参数只是“止痛药”,不是“根治方”。如果应用层还在每个 HTTP 请求都新建连接、Redis 客户端没配连接池、Go 的 http.Transport 没设 MaxIdleConns,那再大的 tcp_max_tw_buckets 也撑不过压测两分钟。
最常被忽略的一点:服务端主动 close() 会让自己进 TIME_WAIT,而客户端主动关则由客户端承担。所以 Nginx、Node.js 等服务端大量 TIME_WAIT 是正常现象——只要不耗尽端口或内存,就不该优先调参,而应让上游调用方启用 Keep-Alive 或连接池。










