TIME_WAIT 是 TCP 连接关闭后的正常状态,但过多的 TIME_WAIT 会耗尽服务器端口资源。本文深入分析 TIME_WAIT 产生原因,提供内核参数调优、连接复用、负载均衡等 5 种解决方案,并通过代码示例演示如何快速定位和优化该问题。
一、TIME_WAIT 的本质与影响
当 TCP 连接主动关闭方(通常是服务端)发送最后一个 ACK 后,会进入 TIME_WAIT 状态并保持 2MSL(默认 60 秒)。这是 TCP 协议确保数据可靠传输的重要机制,但会导致:
- 端口资源耗尽(最多约 28,000 个临时端口)
- 新建连接出现 “Cannot assign requested address” 错误
- 服务器负载升高
二、问题诊断方法
查看 TIME_WAIT 连接统计
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
按端口排序查看
ss -tan state time-wait | sort -k 4
三、5 种核心解决方案
1. 内核参数调优(Linux)
减小 TIME_WAIT 超时(默认 60s)
echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
启用端口快速回收
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
开启连接快速回收(注意 NAT 环境禁用)
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle 4.12+内核已移除
2. 连接池优化
对于数据库等长连接场景:
// HikariCP 配置示例
HikariConfig config = new HikariConfig();
config.setMaximumPoolSize(50);
config.setIdleTimeout(600000); // 10分钟空闲超时
3. HTTP Keep-Alive 配置
Nginx 配置示例
keepalive_timeout 65;
keepalive_requests 100;
4. 负载均衡策略调整
- 避免使用轮询(Round-Robin)
- 优先使用持久化连接(如 IP Hash)
5. 应用层协议优化
对于高频短连接场景,建议:
- 改用 WebSocket 长连接
- 使用 HTTP/2 多路复用
- 实现应用层连接复用
四、生产环境注意事项
- 修改内核参数前需进行压测
- 云服务器注意检查虚拟网络限制
- 监控 TIME_WAIT 数量变化:
watch -n 1 'ss -s | grep time-wait'
评论