Linux 网络连接数暴涨的处理方案

8次阅读

TIME_WaiT是TCP正常关闭的必经状态,持续2×MSL(通常60秒),用于防止旧包干扰新连接;高QPS短连接场景下数量大属正常,非故障,但需排查连接复用缺失或泄漏。

Linux 网络连接数暴涨的处理方案

为什么 netstat 看到大量 TIME_WAIT 连接?

TIME_WAIT 是 TCP 正常关闭的必经状态,持续 2×MSL(通常 60 秒),用于防止旧包干扰新连接。当服务端短连接频繁、QPS 高(如 http API、爬虫探测、健康检查轮询),netstat -ant | grep TIME_WAIT | wc -l 很容易突破几千甚至几万。

  • 这不是故障,但可能掩盖真实问题(比如连接没正确复用、客户端不重用连接)
  • TIME_WAIT 占用的是本地端口 + 四元组,不会耗尽内存,但会占用 net.ipv4.ip_local_port_range 范围内的端口
  • 若端口耗尽(connect() failed: Cannot assign requested address),才真正影响新连接

如何快速判断是否真有连接泄漏?

别只看 TIME_WAIT 数量,先确认是否有未释放的活跃连接:

  • 查看 ESTABLISHED 连接数:ss -snetstat -s | grep -i "established"
  • 按进程统计连接:ss -tunp | awk '{print $7}' | sort | uniq -c | sort -nr | head -10
  • 检查是否有异常 PID 占用大量连接(如某个 python 脚本 fork 出上百个子进程,每个都建新连接)

常见误判点:

  • ss -antnetstat -ant 统计口径略有差异,优先用 ss(更轻量、更准)
  • TIME_WAIT 不等于“卡死”,它不占 socket 缓冲区,也不阻塞 accept()
  • 如果 ESTABLISHED 持续增长且不下降,才要怀疑应用层 close() 缺失或连接池未回收

net.ipv4.tcp_tw_reuse 能不能开?

可以开,但必须满足前提:服务端开启 net.ipv4.tcp_timestamps = 1(默认通常已开)。

  • tcp_tw_reuse = 1 允许内核在 TIME_WAIT 状态下复用端口,仅适用于 客户端主动发起连接 的场景(即本机作为 client)
  • 对于 Web 服务器这类被动监听的服务(server 端),该参数基本无效——因为 server 不需要自己选源端口
  • 开启后需注意:NAT 环境下若客户端时间戳被扭曲,可能引发连接拒绝(极少见,但生产环境建议先小流量验证)

相关配置示例(临时生效):

echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse echo 1 > /proc/sys/net/ipv4/tcp_timestamps

真正有效的压降手段有哪些?

重点不在“消灭 TIME_WAIT”,而在减少短连接频次和提升复用率:

  • 应用层强制使用 HTTP Keep-Alive(如 nginx 中设置 keep-alive_timeout 60s后端语言 client 设置 Connection: keep-alive
  • 客户端启用连接池(Python 用 requests.session()gohttp.DefaultClient.Transport.MaxIdleConns
  • 避免在循环里反复 new client / dial / close(尤其脚本类任务)
  • 如确需高频短连,可适当缩小 net.ipv4.ip_local_port_range(如改为 1024 6553532768 65535),让端口更快耗尽从而触发 tw_reuse 逻辑(副作用是并发上限降低,慎用)

TIME_WAIT 本身不可怕,可怕的是把它当成症状去“治理”,却忽略背后连接模型设计缺陷。真正该盯住的,是 ESTABLISHED 是否稳定、连接建立/关闭是否对称、日志里有没有重复 connect timeoutconnection refused

text=ZqhQzanResources