tcp_tw_recycle参数对connect timed out的影响分析

450 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情

现象

如果客户端连接服务端出现经常性但不是全部的连接超时,比如java应用报错“connect timed out”,则可以检查客户端网络是否使用了SNAT,而服务端主机开启了tcp_tw_recycle=1参数,如果是,则超时问题大概率是由此引起的。

解决方案

服务端关闭tcp_tw_recycle,这个参数已经弃用,建议在任何时候都保持关闭。

原因分析

服务端打开了 tcp_tw_reccycle 参数,就会检查时间戳;客户端使用SNAT,发来的包的时间戳是乱跳的(截图时间字段,如果客户端发来的时间戳是滞后的,这样的包服务端肯定不会回复),所以服务器就把带了“倒退”的时间戳的包当作是“recycle的tw连接的重传数据,不是新的请求”,于是丢掉不回包,造成对方大量超时。

原理

TCP连接四次挥手与TIMEWAIT

timewait状态表示主动关闭方收到了被动关闭方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN_WAIT_1状态下,收到了被动关闭方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。

timewait的相关重要参数

net.ipv4.tcp_timestamp=1

两端同时开启有效,在tcp分组中加入ts val和 ecr 时间戳信息,如其不开启,则recycle和reuse均不生效

net.ipv4.tcp_tw_recycle=0

time_wait快速回收,此功能生效后,对ts val进行校验,对端同一ip的包,ts val小于之前包的会丢弃 net.ipv4.tcp_tw_reuse=1 客户端发起新连接可重用超1秒的time_wait(个人理解),内网的话,问题不大

net.ipv4.tcp_max_tw_buckets=262144

限制tw的数量