服务器出现大量 TIME_WAIT 是什么原因?

2025.7.7 杂七杂八 1393
33BLOG智能摘要
服务器因主动关闭连接在TCP四次挥手中进入TIME_WAIT状态而出现大量堆积。排查发现是由于Java应用服务器连接池配置过小(仅为10个连接)而QPS超过200导致。解决方案包括将连接池调整至50个,启用tcp_tw_reuse,谨慎使用tcp_tw_recycle,以及优化应用代码确保正确关闭连接。修改相关参数后,TIME_WAIT数量迅速下降。提醒在NAT环境下应避免使用tcp_tw_recycle以防误杀合法连接。
— 此摘要由33BLOG基于AI分析文章内容生成,仅供参考。

服务器TIME_WAIT堆积如山?这是我踩过的坑和解决方案

服务器出现大量 TIME_WAIT 是什么原因?

大家好,我是33blog的技术博主。上周我们的生产环境突然出现了一个奇怪的问题:服务器响应变慢,通过netstat -antp一看,好家伙,TIME_WAIT状态的连接数竟然达到了惊人的3万+!今天我就来分享一下这次排查的全过程。

什么是TIME_WAIT状态?

在TCP四次挥手过程中,主动关闭连接的一方会进入TIME_WAIT状态。这个状态会持续2MSL(Maximum Segment Lifetime,报文最大生存时间,通常为60秒)。

用大白话解释就是:当你的服务器主动关闭连接后,它会在内存里保留这个连接的信息一段时间,防止网络中还有延迟的数据包到达。

为什么会出现大量TIME_WAIT?

根据我的经验,常见原因有:

  • 短连接泛滥:每次请求都新建连接,用完就关
  • 连接池配置不当:连接池太小导致频繁创建新连接
  • 服务器主动关闭连接:比如Nginx默认会主动关闭空闲连接
  • TCP参数配置不合理:比如tcp_tw_reusetcp_tw_recycle设置不当

我是如何排查的?

首先用这个命令查看TIME_WAIT连接情况:

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

输出类似这样:

TIME_WAIT 32456
ESTABLISHED 23
CLOSE_WAIT 5

然后通过lsof -i:端口号发现大部分都是来自我们的Java应用服务器。进一步检查发现是连接池配置太小(只有10个连接),而QPS有200+,这明显不够用啊!

解决方案

经过多次测试,我采取了以下措施:

  1. 增大连接池:将连接池大小调整到50
  2. 启用TCP重用:修改/etc/sysctl.conf
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_tw_recycle = 1  # 注意:NAT环境下慎用!
    net.ipv4.tcp_fin_timeout = 30
  3. 优化应用代码:确保正确关闭连接,避免泄漏

修改后执行sysctl -p生效,TIME_WAIT数量很快降到了正常水平。

血泪教训

这里要特别提醒大家:tcp_tw_recycle在NAT环境下会导致严重问题!我们测试环境就因此出现过连接失败的情况。后来查阅资料才知道,这个参数会基于时间戳拒绝”过时”的报文,而在NAT环境下可能误杀合法连接。

所以我的建议是:生产环境慎用tcp_tw_recycle,优先考虑增大连接池和设置tcp_tw_reuse

总结

遇到TIME_WAIT堆积不要慌,按照这个思路排查:

  1. 确认是否是短连接导致
  2. 检查连接池配置
  3. 合理调整TCP参数
  4. 监控效果,持续优化

希望我的这次踩坑经历能帮到你们。如果你也遇到过类似问题,欢迎在评论区分享你的解决方案!

评论

  • 遇到过同样的问题!连接池配太小真是太坑了,感谢分享解决方案 👍

  • 想问下大佬,tcp_tw_recycle在云服务器上是不是也会有问题?我们在腾讯云上遇到过

  • 说得很详细!原来NAT环境下tcp_tw_recycle会有问题,学到了 🤔