服务器TIME_WAIT堆积如山?这是我踩坑后总结的排查指南
上周五深夜,我的手机突然被运维告警轰炸——线上服务器出现大量TIME_WAIT连接。作为一个经历过多次网络问题摧残的老兵,我立刻意识到这可能是性能问题的前兆。今天就来和大家聊聊这个看似普通却暗藏杀机的TCP状态。
一、TIME_WAIT到底是什么鬼?
记得刚入行时,我第一次在netstat -ant
看到满屏的TIME_WAIT时,还以为服务器被黑了。其实这是TCP协议完全正常的关闭流程:当主动关闭连接的一方(通常是我们的服务器),在发送最后一个ACK后就会进入这个状态。
用大白话解释就是:“我知道咱俩要分手了,但我得再等会儿,确保你收到我的分手信”。这个等待时间在Linux上默认是60秒(2MSL),期间这个连接会占用着端口资源。
二、为什么我的服务器特别多?
通过ss -s
命令,我发现某台机器上TIME_WAIT竟然有3万多个!常见的罪魁祸首有:
- 短连接泛滥:比如HTTP服务没有启用KeepAlive
- 频繁创建销毁连接:特别是微服务间调用
- 端口耗尽预警:当接近28,000个时会触发问题
我遇到过最坑的情况是某个新人写的脚本,每次请求都新建连接,完事就close,活生生把服务器拖垮。
三、实战排查四部曲
分享我的诊断套路,用到的命令建议收藏:
# 1. 查看总体统计
ss -s
# 2. 按状态过滤
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
# 3. 查看占用最多的IP
netstat -n | grep TIME_WAIT | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr
# 4. 内核参数检查
sysctl net.ipv4.tcp_fin_timeout
四、解决方案与踩坑记录
根据场景不同,我常用的解决手段:
- 启用连接复用:比如Nginx的keepalive_timeout
- 调整内核参数(谨慎操作):
# 缩短TIME_WAIT超时(建议30s左右) echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout # 开启端口复用 echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
- 连接池优化:数据库/Redis等中间件连接池配置
⚠️ 警告:曾经有同事把tcp_tw_recycle
和NAT网络混用,直接导致线上事故!这个参数在4.12内核后已被移除。
五、什么时候该紧张?
不是所有TIME_WAIT都需要处理。我的经验法则:
- 当数量超过2万且持续增长
- 开始出现
Cannot assign requested address
错误 - 伴随明显的性能下降
最后说个冷知识:Windows系统的默认MSL是2分钟,是Linux的两倍。所以跨平台开发时,测试环境可能发现不了这个问题…
大家有没有遇到过更奇葩的TIME_WAIT案例?欢迎在评论区分享你的血泪史~
这篇文章讲得太及时了,我们公司最近也遇到TIME_WAIT爆炸的问题,看完终于知道该怎么查了!
tcp_tw_reuse这个参数真的慎用啊,上次我改完直接线上炸了😅
想问下作者,除了ss和netstat,还有没有其他工具可以看这个状态?