Time_wait状态
- 表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。
- 如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。
Time_wait作用
1)可靠地实现TCP全双工连接的终止
TCP协议在关闭连接的四次握手过程中,最终的ACK是由主动关闭连接的一端(后面统称A端)发出的,如果这个ACK丢失,对方(后面统称B端)将重发出最终的FIN,因此A端必须维护状态信息(TIME_WAIT)允许它重发最终的ACK。如果A端不维持TIME_WAIT状态,而是处于CLOSED 状态,那么A端将响应RST分节,B端收到后将此分节解释成一个错误(在java中会抛出connection reset的SocketException)。
因而,要实现TCP全双工连接的正常终止,必须处理终止过程中四个分节任何一个分节的丢失情况,主动关闭连接的A端必须维持TIME_WAIT状态 。
2)允许老的重复分节在网络中消逝
TCP分节可能由于路由器异常而“迷途”,在迷途期间,TCP发送端可能因确认超时而重发这个分节,迷途的分节在路由器修复后也会被送到最终目的地,这个迟到的迷途分节到达时可能会引起问题。在关闭“前一个连接”之后,马上又重新建立起一个相同的IP和端口之间的“新连接”,“前一个连接”的迷途重复分组在“前一个连接”终止后到达,而被“新连接”收到了。为了避免这个情况,TCP协议不允许处于TIME_WAIT状态的连接启动一个新的可用连接,因为TIME_WAIT状态持续2MSL,就可以保证当成功建立一个新TCP连接的时候,来自旧连接重复分组已经在网络中消逝。
2MSL
- MSL是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”。
- 他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。
- RFC 793中规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等。
Time_wait参数调优
1、添加到/etc/sysctl.conf
# 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用Cookie来处理,可防范少量的SYN攻击。该参数默认为0,表示关闭。
net.ipv4.tcp_syncookies=1 # 表示开启重用,即允许将TIME-WAIT套接字重新用于新的TCP连接。该参数默认为0,表示关闭。
net.ipv4.tcp_tw_reuse=1 # 表示开启TCP连接中TIME-WAIT套接字的快速回收,该参数默认为0,表示关闭。
net.ipv4.tcp_tw_recycle=1 # 表示如果套接字由本端要求关闭,那么这个参数将决定它保持在FIN-WAIT-2状态的时间。
net.ipv4.tcp_fin_timeout=30 # 表示当Keepalived启用时,TCP发送Keepalived消息的频度改为20分钟,默认值是2小时。
net.ipv4.tcp_keepalive_time=1200 # 表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息,默认值为180 000,此处改为5000。对于Apache、Nginx等服务器,前面介绍的几个参数已经可以很好地减少TIME_WAIT套接字的数量,但是对于Squid来说,效果却不大,有了此参数就可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。
net.ipv4.tcp_max_tw_buckets=5000
2、生效内核参数。
sysctl -p /etc/sysctl.conf