time-wait状态如何产生的 如何避免

1如何产生的
close()发起主动关闭的一方,在发送最后一个ACK之后会进入time_wait的状态,也就说该发送方会保持2MSL时间之后才会回到初始状态。MSL值得是数据包在网络中的最大生存时间 linux默认时间是60s
为什么time_wait出现在主动关闭的一端:假设最终的ACK丢失了,服务器将重新发送他的最终FIN,因此客户必须维护状态信息,因为可能不得不重传最终那个ACK。

2产生原因
为实现TCP全双工连接的可靠释放
为使旧的数据包在网络因过期而消失

3如何避免

1 :多IP 增加随机端口 (最优解决方案)
目前nginx好像不支持多ip
haproxy 支持多ip

2 内核调优
首先服务器可以设置SO_REUSEADDR(端口复用)套接字选项来通知内核,如果端口忙,但TCP连接位于TIME_WAIT状态时可以重用端口。在一个非常有用的场景就是,如果你的服务器程序停止后想立即重启,而新的套接字依旧希望使用同一端口,此时SO_REUSEADDR选项就可以避免TIME_WAIT状态。
系统默认关闭端口如用
cat /proc/sys/net/ipv4/tcp_tw_reuse
开启端口复用
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse

cat /proc/sys/net/ipv4/tcp_timestamps 时间戳 默认开启 必须开启 除非大数据要求性能不考虑timewait 情况关闭 端口复用下需要依赖时间戳才能避免数据混乱

cat /proc/sys/net/ipv4/tcp_tw_recycle 快速回收 在客户端是NAT模式下可能会出现问题 尽量不要开
cat /proc/sys/net/ipv4/tcp_tw_reuse 端口复用 安全的
cat /proc/sys/net/ipv4/tcp_fin_timeout 修改系统默认timeout时间 默认60
在NAT模式下,会出现时间戳错乱的现象(因为NAT模式下向RealServer发送的请求报文中的源地址都是负载均衡服务器的IP),于是后面的数据包就被丢弃了,具体的表现通常是是客户端明明发送的SYN,但服务端就是不响应ACK。必须同时激活tcp_timestamps和tcp_tw_recycle才会触发这种现象,如果服务器身处NAT环境,安全起见,通常要禁止tcp_tw_recycle,也可以关闭tcp_timestamps 开启tcp_tw_recycle这种方法应该也是可行的,不过最好多做测试,以防有其他的副作用

3 通过长链接
因为timewait只会出现在主动关闭的一方,所以使用长链接减少TCP 连接与断开 比如web服务器访问后端数据库或redis如果不适用长链接就会出现大量timewait

为什么要研究time-wait
因为一个timewait对于web服务器来说占用了一个socket 60秒 socket的数量是有限的 最多65535 在内核调优的情况下1024-65535个

你可能感兴趣的:(网络)