千万别忽视!TIME_WAIT 堆积背后的秘密和应对技巧
平时运维过程中,你有没有遇到过这种情况:服务器明明没多少请求,但 netstat -an | grep tcp | grep TIME_WAIT 一看,成千上万条 TIME_WAIT 堆积,看着被攻击了一样。
别慌,这不是 Bug,这就是 TCP 的自我保护机制。今天,我帮你彻底弄懂 TIME_WAIT,顺便教你怎么解决它。
1. TIME_WAIT 是什么?
TCP 连接关闭有个“四次挥手”的过程:
- 客户端发 FIN:我要关闭连接
- 服务器回 ACK:收到
- 服务器发 FIN:我也要关闭
- 客户端回 ACK
主动关闭的一方就会进入 TIME_WAIT,等待 2×MSL(最大报文生存时间),Linux 默认大约 60 秒。
为什么要等?保证最后的 ACK 能被对方收到,避免网络延迟导致数据丢失。
简单来说,TIME_WAIT 就是 TCP 的“安全休眠模式”。
2. 为什么会产生大量 TIME_WAIT?
可能有以下几个原因:
- 短连接频繁建立:HTTP、Redis、MySQL 的短连接模式,每次请求都是一次开关机,TIME_WAIT 自然堆积。
- 服务器主动关闭:TIME_WAIT 只出现在主动关闭连接的一方,如果服务端经常主动断开,而客户端被动接受,就会堆很多。
- 高并发环境:短时间内大量连接关闭,TIME_WAIT 就像小人潮,堆积在系统里。
3. TIME_WAIT 有啥影响?
如果TIME_WAIT堆积过多,会出现下面的问题:
- 端口耗尽:每个 TIME_WAIT 占用一个端口,如果端口被短时间内重复使用,可能会遇到“端口不够用”的尴尬。
- 占用内存:每个 TIME_WAIT 会占用少量内存,但 Linux 可以处理大量 TIME_WAIT,一般不会直接 OOM。
换句话说,大量 TIME_WAIT 很正常,不必慌,除非端口用完。
4. 解决方案
(1) TCP 端口重用
允许系统复用 TIME_WAIT 端口,避免端口耗尽。
sysctl -w net.ipv4.tcp_tw_reuse=1
注意:只对客户端主动发起连接有效。
(2) 缩短 TIME_WAIT 时间
减少 TIME_WAIT 保持时间,加快回收。
sysctl -w net.ipv4.tcp_fin_timeout=30
默认约 60 秒,时间太短可能增加重传风险。
(3) 使用长连接 / 连接池
- HTTP:开启 Keep-Alive,减少重复连接
- 数据库:使用连接池复用连接
以Nginx为例:
keepalive_timeout 65;
keepalive_requests 100;
(4) 负载均衡
使用 Nginx、LVS、HAProxy,把高并发连接分散到多台服务器,减少单台压力。
核心思路:减少新连接产生 + 缩短或复用 TIME_WAIT + 分散压力
TIME_WAIT 是 TCP 的“安全休眠”,高并发环境堆积很正常。掌握以上方法,就能让 Linux 服务器更稳、更快、更抗压。