记录一次:TIME_WAIT状态连接过多的分析与解决
原理说明
一个连接的建立与断开,正常过程至少需要来回7个包才能完成。
Each socket in TIME_WAIT consumes some memory in the kernel, usually somewhat less than an ESTABLISHED socket yet still significant. A sufficiently large number could exhaust kernel memory, or at least degrade performance because that memory could be used for other purposes. TIME_WAIT sockets do not hold open file descriptors (assuming they have been closed properly), so you should not need to worry about a "too many open files" error.
Time wait 中的每个套接字都会消耗内核中的一些内存,通常比 ESTABLISHED 套接字少一些,但仍然很重要。 一个足够大可能耗尽内核内存,或者至少降低性能,因为内存可以用于其他目的。 Time wait sockets 不保存打开的文件描述符(假设它们已经正确关闭) ,因此不需要担心"打开的文件太多"错误。
The socket also ties up that particular src/dst IP address and port so it cannot be reused for the duration of the TIME_WAIT interval. (This is the intended purpose of the TIME_WAIT state.) Tying up the port is not usually an issue unless you need to reconnect a with the same port pair. Most often one side will use an ephemeral port, with only one side anchored to a well known port. However, a very large number of TIME_WAIT sockets can exhaust the ephemeral port space if you are repeatedly and frequently connecting between the same two IP addresses. Note this only affects this particular IP address pair, and will not affect establishment of connections with other hosts.
套接字还绑定了特定的 src / dst IP 地址和端口,因此在 TIME wait 间隔期间不能重用它。 (这是 TIME wait 状态的预期用途。) 连接端口通常不是问题,除非您需要重新连接到相同的端口对。 大多数情况下,一方将使用临时港口,只有一方锚定在一个著名的港口。 但是,如果在相同的两个 IP 地址之间重复且频繁地连接,大量的 TIME wait 套接字可能会耗尽临时端口空间。 请注意,这只影响这个特定的 IP 地址对,并不会影响与其他主机建立连接。
TCP 连接必须经过时间 2MSL 后才真正释放掉(2MSL 的时间的用意 --- 为了保证 A 发送的最后一个 ACK 报文段能够到达 B.防止 “已失效的连接请求报文段”出现在本连接中.A 在发送完最后一个 ACK 报文段后,再经过时间 2MSL,就可以使本连接持续的时间内所产生的所有报文段,都从网络中消失.这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段)
如果许多连接正在被快速打开和关闭,可能会引起大量的 TIME_WAIT 连接。
这会引发端口资源或其他资源的消耗,如果达到上限,那么就会引发创建新连接的障碍。
TIME_WAIT状态的连接过多导致系统端口资源耗尽
大量的TIME_WAIT进程。简单来说,每一个tcp连接关闭后,主动关闭方都会保留这个连接一段时间,这个时间内,这个连接的状态是TIME_WAIT,端口资源不会被释放。这个超时时间为2*MSL。RFC 793中规定MSL为2分钟,实际由系统决定,通常在30-120s。这个网上有很多详细解释,这里不过多阐述。因为连接的关闭释放有一定时间,并不是程序运行完就立刻释放端口资源,所以当申请的连接进程较多的时候,端口资源就不够用了。系统默认可用的端口资源:
$ cat /proc/sys/net/ipv4/ip_local_port_range
32768 61000
解决办法:
1 扩大资源可用
# 扩大端口范围,增加端口资源
net.ipv4.ip_local_port_range = 1024 65535
#开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0
net.ipv4.tcp_tw_reuse = 1
2. 优化自己的系统,减少短连接次数
因为tcp连接关闭后是有必要保留一段时间TIME_WAIT状态的,我们的目标不应该是简单的缩短TIME_WAIT时间,而是应该从根本上去优化我们的系统架构设计,减少不必要的短连接请求。
参考资料
What is the cost of many TIME_WAIT on the server side? 在服务器端进行多次 TIME wait 的成本是多少?
https://stackoverflow.com/questions/1803566/what-is-the-cost-of-many-time-wait-on-the-server-side
(传输层)TCP协议
http://www.cnblogs.com/kzloser/articles/2582957.html
TIME_WAIT状态的连接过多导致系统端口资源耗尽问题(2)
https://www.cnblogs.com/wangsili/p/3958371.html