
本文共 1484 字,大约阅读时间需要 4 分钟。
解决TIME_WAIT过多导致无法对外建立新连接的问题
问题背景
近期在线上项目中遇到了一道难题:服务器出现大量TIME_WAIT状态的TCP连接,导致其无法与下游模块建立新HTTP连接。这一问题经过查阅经典教材和技术文章,加深了对TCP网络问题的理解。本文将详细记录解决过程。
1. 初步问题定位
通过初步查看发现,无法对外新建TCP连接时,线上服务器存在大量处于TIME_WAIT状态的TCP连接(最多的一次为单机10w+,其中引起报警的那个模块产生的TIME_WAIT约2w),导致其无法跟下游模块建立新TCP连接。
2. TCP状态迁移
TCP连接的状态机包含11个状态,TIME_WAIT
是连接被一方主动关闭后进入的状态,表示等待对方的重传请求或确认。TIME_WAIT
状态的持续时间由MSL
(Max Segment Lifetime)决定,通常为2MSL(2分钟)。这一状态会阻止该端口立即被用于新连接。
3. 系统配置分析
通过查看系统网络配置,发现以下关键参数:
tcp_max_tw_buckets
:默认值为180000,用于限制系统同时持有的TIME_WAIT
连接数。超过该限制会销毁连接并报警。tcp_tw_recycle
:默认值为0,用于快速回收TIME_WAIT
连接的socket资源。tcp_tw_reuse
:默认值为0,允许在安全条件下复用TIME_WAIT
连接。
这些参数的设置直接影响了TCP连接的状态管理。
4. 问题定位
通过netstat –at | grep "TIME_WAIT"
统计发现,问题机器存在大量TIME_WAIT
连接。进一步分析发现,由报警模块引起的TIME_WAIT
连接有2w+,占用了大量本地端口资源。这表明系统无法分配新的端口来建立新连接。
5. 解决方法
针对该问题,可以采取以下措施:
5.1 系统配置优化
tcp_max_tw_buckets
:默认值为180000,可以根据实际负载适当调大。tcp_tw_recycle
:在shell中执行echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
,加速TIME_WAIT
连接的回收。tcp_tw_reuse
:执行echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
,允许在安全条件下复用TIME_WAIT
连接。5.2 应用程序优化
SO_LINGER
选项:通过setsockopt
控制socket的linger
时间,优化连接释放策略。6. 注意事项
tcp_tw_reuse
选项的使用:必须同时开启tcp_timestamps
,否则tcp_tw_reuse
无效。- 网络环境的影响:在NAT或防火墙环境下开启
tcp_tw_recycle
可能导致SYN包被直接丢弃,需谨慎操作。
7. 实际案例分析
在实际操作中,发现问题并非仅由TIME_WAIT
导致。某次操作中,未仔细检查curl日志,误以为问题由TIME_WAIT
引起,结果发现下游模块对访问IP进行了防攻击限制。因此,定位问题时需结合应用日志和错误信息。
8. 总结
TIME_WAIT
过多导致无法建立新连接的主要原因是端口资源耗尽。通过调整系统配置和优化应用程序,可以有效缓解该问题。建议在实际应用中结合具体场景,灵活配置tcp_max_tw_buckets
、tcp_tw_recycle
和tcp_tw_reuse
选项,同时关注网络环境的影响。
发表评论
最新留言
关于作者
