什么原因会导致开启如此多的TIME_WAIT连接?

13

因此,我在一个服务器上有应用程序A,它每秒向另一个服务器上的应用程序B发送710个HTTP POST消息,该应用程序在单个端口上侦听。这些连接不是保持活动状态的;它们被关闭。

几分钟后,应用程序A报告说它无法打开到应用程序B的新连接。

我在两台机器上持续运行netstat,并看到大量TIME_WAIT连接在每台机器上都处于打开状态。几乎所有显示的连接都在TIME_WAIT状态。根据在线阅读,似乎这是在每一方关闭连接后30秒钟(根据我们机器上/proc/sys/net/ipv4/tcp_fin_timeout值为30秒)所处的状态。

我在每台机器上都运行了一个脚本,不断执行以下操作:

netstat -na | grep 5774 | wc -l

以及:

netstat -na | grep 5774 | grep "TIME_WAIT" | wc -l

在每台机器上,每个应用程序似乎都会达到大约28,000左右的值,然后应用程序A报告说无法打开与应用程序B的新连接。

我读到了这个文件:/proc/sys/net/ipv4/ip_local_port_range,它提供了可以同时打开的连接总数:

$ cat /proc/sys/net/ipv4/ip_local_port_range 32768 61000

61000 - 32768 = 28232,这与我看到的大约28,000个TIME_WAIT一致。

我的问题是如何可能有这么多处于TIME_WAIT状态的连接。

每秒关闭710个连接,我应该在任意时刻看到大约710 * 30秒 = 21300个连接。我想只是因为每秒有710个连接被打开,并不意味着每秒都有710个连接被关闭...

我能想到的唯一其他原因就是操作系统缓慢地关闭连接。

1个回答

13

TCP的TIME_WAIT表示本地端点(这一侧)已关闭连接。保留连接是为了能够将任何延迟的数据包与连接匹配并适当处理。这些连接将在四分钟内超时后被删除。

假设所有这些连接都是有效的,那么一切都正常工作。您可以通过让远程端关闭连接或修改系统参数来消除TIME_WAIT状态(尽管这样做可能会有危险)。

Vincent Bernat有一篇关于TIME_WAIT及其处理方法的优秀文章

Linux内核文档对net.ipv4.tcp_tw_recycle的解释不太有帮助:

启用快速回收TIME-WAIT套接字。默认值为0。不建议未经技术专家的建议/请求进行更改。

它的同级项net.ipv4.tcp_tw_reuse稍微有点更详细的说明,但语言也大致相同:

允许在协议视角安全时重用TIME-WAIT套接字以进行新连接。默认值为0。不建议未经技术专家的建议/请求更改此设置。
缺乏文档说明的结果是,我们发现许多调整指南建议将这两个设置都设置为1,以减少TIME-WAIT状态中的条目数。然而,正如tcp(7)手册页面所述,对于面向公众的服务器来说,net.ipv4.tcp_tw_recycle选项非常有问题,因为它无法处理来自同一NAT设备后面的两台不同计算机的连接,这是一个难以检测并等待咬你的问题:
启用快速回收TIME-WAIT套接字。不建议启用此选项,因为在使用NAT(网络地址转换)时会导致问题。

1
为什么是4分钟?你是说我的/proc/sys/net/ipv4/tcp_fin_timeout值为30秒是无效的吗? - vmayer
谢谢,我会看一下你的文章。至于TIME_WAIT的定义,根据这个图表,我觉得双方都已经关闭了连接,而不仅仅是这一方:http://www.cs.northwestern.edu/~agupta/cs340/project2/TCPIP_State_Transition_Diagram.pdf。如果我看错了或者有什么问题,请告诉我。 - vmayer
好的,现在我认为30秒是MSL,并且TIME_WAIT状态是这个时间的两倍,因此是60秒,因为在你提供的文章中它说:“RFC 793要求TIME-WAIT状态持续的时间是MSL的两倍。” - vmayer
是的,双方都关闭了,但是TIME_WAIT只会在本地端先关闭时发生。该状态的目的是清除正在传输中的数据包。如果您的连接全部都是本地的,那么这就不是一个大问题。但如果它们位于地球的另一侧,那就可能会有问题。 - Brian White

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接