你有没有遇到过这种情况:服务器明明没多少请求,但 netstat -an | grep tcp | grep TIME_WAIT 一看,成千上万条 TIME_WAIT 堆积,看着被攻击了一样。

别慌,这不是 Bug,这就是 TCP 的自我保护机制。今天,我帮你彻底弄懂 TIME_WAIT,顺便教你怎么解决它。

1 TIME_WAIT 是什么?

TCP 连接关闭有个“四次挥手”的过程:

  1. 客户端发 FIN:我要关闭连接

  2. 服务器回 ACK:收到

  3. 服务器发 FIN:我也要关闭

  4. 客户端回 ACK

主动关闭的一方就会进入 TIME_WAIT,等待 2×MSL(最大报文生存时间),Linux 默认大约 60 秒

为什么要等?保证最后的 ACK 能被对方收到,避免网络延迟导致数据丢失。

简单来说,TIME_WAIT 就是 TCP 的“安全休眠模式”。

2 为什么会产生大量 TIME_WAIT?

可能有以下几个原因:

短连接频繁建立

HTTP、Redis、MySQL 的短连接模式,每次请求都是一次开关机,TIME_WAIT 自然堆积。
  1. 服务器主动关闭

    TIME_WAIT 只出现在主动关闭连接的一方,如果服务端经常主动断开,而客户端被动接受,就会堆很多。

  2. 高并发环境

    短时间内大量连接关闭,TIME_WAIT 就像小人潮,堆积在系统里。

3 TIME_WAIT 有啥影响?

如果TIME_WAIT堆积过多,会出现下面的问题:

  • 端口耗尽

    每个 TIME_WAIT 占用一个端口,如果端口被短时间内重复使用,可能会遇到“端口不够用”的尴尬。

  • 占用内存

    每个 TIME_WAIT 会占用少量内存,但 Linux 可以处理大量 TIME_WAIT,一般不会直接 OOM。

换句话说,大量 TIME_WAIT 很正常,不必慌,除非端口用完。

4 解决方案

4.1 TCP 端口重用

允许系统复用 TIME_WAIT 端口,避免端口耗尽。

sysctl -w net.ipv4.tcp_tw_reuse=1

注意:只对客户端主动发起连接有效。

4.2 缩短 TIME_WAIT 时间

减少 TIME_WAIT 保持时间,加快回收。

sysctl -w net.ipv4.tcp_fin_timeout=30

默认约 60 秒,时间太短可能增加重传风险。

4.3 使用长连接 / 连接池

  • HTTP:开启 Keep-Alive,减少重复连接

  • 数据库:使用连接池复用连接

以Nginx为例:

keepalive_timeout 65;
keepalive_requests 100;

4.4 负载均衡

使用 Nginx、LVS、HAProxy,把高并发连接分散到多台服务器,减少单台压力。

核心思路:减少新连接产生 + 缩短或复用 TIME_WAIT + 分散压力

TIME_WAIT 是 TCP 的“安全休眠”,高并发环境堆积很正常。掌握以上方法,就能让 Linux 服务器更稳、更快、更抗压。