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
来源: http://www.bubuko.com/infodetail-3462211.html