time_wait状态

处于该状态下的TCP连接不能立即以同样的四元组建立新连接
一、作用
1)实现TCP全双工连接的可靠释放
确保被动关闭方收到ACK,连接正常关闭,且不因被动关闭方重传FIN影响下一个新连接
2)使旧的数据包在网络因过期而消失
2MSL:报文最大生存时间,确保旧的数据不会影响新连接

二、带来的问题
1) 作为服务器,短时间内关闭了大量的Client连接,就会造成服务器上出现大量的TIME_WAIT连接,占据大量的tuple,严重消耗着服务器的资源;
2) 作为客户端,短时间内大量的短连接,会大量消耗的Client机器的端口,毕竟端口只有65535个,端口被耗尽了,后续就无法在发起新的连接了。

三、解决办法
1)快速回收Time_wait
net.ipv4.tcp_tw_recycle = 1表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。Linux下快速回收的时间为3.5 * RTO(Retransmission Timeout),而一个RTO时间为200ms至120s。
TCP有一种行为,可以缓存每个连接最新的时间戳,后续请求中如果时间戳小于缓存的时间戳,即视为无效,相应的数据包会被丢弃。Linux是否启用这种行为取决于tcp_timestamps和tcp_tw_recycle,因为tcp_timestamps缺省就是开启的,所以当tcp_tw_recycle被开启后,实际上这种行为就被激活了。在nat环境中会出现时间戳错乱的情况,后面的数据包就被丢弃了,具体的 表现通常是是客户端明明发送的SYN,但服务端就是不响应ACK。因为NAT设备将数据包的源IP地址都改成了一个地址(或者少量的IP地址),但是却基本上不修改TCP包的时间戳,则会导致时间戳混乱。建议:如果前端部署了三/四层NAT设备,尽量关闭快速回收,以免发生NAT背后真实机器由于时间戳混乱导致的SYN拒绝问题。

tcp_timestamps 引起的问题:
https://blog.csdn.net/feiying00544/article/details/83115471
2)重用Time_wait
net.ipv4.tcp_tw_reuse = 1
如果能保证以下任意一点,一个TW状态的四元组(即一个socket连接)可以重新被新到来的SYN连接使用:
1.初始序列号比TW老连接的末序列号大
2.如果使能了时间戳,那么新到来的连接的时间戳比老连接的时间戳大

3)修改tcp_max_tw_buckets:
tcp_max_tw_buckets 控制并发的TIME_WAIT的数量,默认值是180000。如果超过默认值,内核会把多的TIME_WAIT连接清掉,然后在日志里打一个警告。官网文档说这个选项只是为了阻止一些简单的DoS攻击,平常不要人为的降低它;
4)利用RST包从外部清掉TIME_WAIT链接

四、tcp_tw_reuse和SO_REUSEADDR
tcp_tw_reuse是内核选项,而SO_REUSEADDR用户态的选项,使用SO_REUSEADDR是告诉内核,如果端口忙,但TCP状态位于 TIME_WAIT ,可以重用端口。如果端口忙,而TCP状态位于其他状态,重用端口时依旧得到一个错误信息, 指明Address already in use”。如果你的服务程序停止后想立即重启,而新套接字依旧使用同一端口,此时 SO_REUSEADDR 选项非常有用。

SO_REUSEADDR允许完全重复的捆绑:
当一个IP地址和端口绑定到某个套接口上时,还允许此IP地址和端口捆绑到另一个套接口上。一般来说,这个特性仅在支持多播的系统上才有,而且只对UDP套接口而言(TCP不支持多播)。

  • 42
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值