TIME_WAIT状态是怎么来的
在TCP协议里,每次断开连接时,主动关闭的一方会进入TIME_WAIT状态。这个状态默认持续60秒,主要是为了确保对方收到最后的ACK确认包,防止旧连接的数据包干扰新连接。这本来是个好设计,但在高并发场景下,问题就来了。
比如你运营一个电商网站,大促期间每秒成千上万的请求进来,每个请求处理完都要断开连接。如果后端服务是主动关闭的一方,那服务器上就会积累大量处于TIME_WAIT状态的连接。
连接数被占满,新用户进不来
一台服务器能打开的端口总数是有限的,通常是65535个。当大量端口被TIME_WAIT占用,新的客户端请求就没法建立连接了。用户刷新页面卡住,下单失败,客服电话立马被打爆。这种情况在负载均衡器或反向代理(比如Nginx)后面特别常见,因为它们往往代为关闭后端连接。
内存和CPU压力悄悄上升
每个TIME_WAIT连接虽然不传输数据,但内核还是要为它保留一点信息,比如端口号、IP地址、状态等。几万个连接堆在一起,内存消耗不容小觑。更麻烦的是,系统要定期扫描这些连接,看看是否到期可回收,这会增加CPU负担。
有次某公司API网关突然变慢,查了一圈才发现TIME_WAIT连接超过15万,服务器负载直接飙到20以上。
怎么缓解这个问题
先别急着改内核参数。真正的解法是从业务层面减少短连接的使用。比如让客户端启用Keep-Alive,复用同一个连接发多个请求,这样一天只断一次连接,而不是每秒断几千次。
实在改不了,再考虑调整系统设置。比如开启TIME_WAIT快速回收(注意可能受NAT影响),或者开启端口重用:
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 0 # 在NAT环境下建议关闭
net.ipv4.tcp_fin_timeout = 30还可以调小FIN超时时间,让连接早点释放。不过这些都属于“打补丁”,根子还是得看架构有没有优化空间。
见过一个案例,某内部系统每分钟调用上千次外部接口,全用短连接。改成连接池之后,TIME_WAIT从两万多降到几百,响应速度也快了一倍。
监控比调优更重要
平时多留意服务器的连接状态。用这条命令就能看到情况:
ss -tan | grep TIME-WAIT | wc -l要是数字经常上万,就得警惕了。与其等到服务瘫痪再救火,不如提前把连接管理做好。