73

我们正在尝试调整一个通过 TCP 接受消息并使用 TCP 进行一些内部消息传递的应用程序。在负载测试时,我们注意到响应时间显着降低(然后完全停止),因为系统同时发出更多请求。在此期间,我们看到很多 TCP 连接处于TIME_WAIT状态,有人建议将TIME_WAIT环境变量从默认的 60 秒降低到 30 秒。

我了解,该TIME_WAIT设置实质上设置了连接关闭后 TCP 资源再次可供系统使用的时间。

我不是“网络人”,对这些事情知之甚少。我需要该链接帖子中的很多内容,但有点“笨拙”。

  • 我想我明白为什么TIME_WAIT不能将值设置为 0,但可以安全地设置为 5 吗?10个呢?什么决定了这个值的“安全”设置?
  • 为什么这个值的默认值为 60?我猜想比我聪明得多的人有充分的理由选择它作为合理的默认值。
  • 关于覆盖此值的潜在风险和收益,我还应该知道什么?
4

7 回答 7

103

TCP 连接由元组(源 IP、源端口、目标 IP、目标端口)指定。

会话关闭后出现 TIME_WAIT 状态的原因是,网络中可能仍有实时数据包在发送给您的途中(或来自您的可能会请求某种响应的数据包)。如果您要重新创建相同的元组并且其中一个数据包出现,它将被视为您的连接的有效数据包(并且可能由于排序而导致错误)。

所以TIME_WAIT时间一般设置为包最大年龄的两倍。该值是在网络丢弃数据包之前允许数据包到达的最长时间。

这保证了,在您被允许使用相同的元组创建连接之前,属于该元组先前化身的所有数据包都将失效。

这通常决定了您应该使用的最小值。最大数据包寿命由网络属性决定,一个例子是卫星寿命高于 LAN 寿命,因为数据包还有很长的路要走。

于 2008-12-03T13:46:17.170 回答
21

通常,只有发出“主动关闭”的端点才应该进入 TIME_WAIT 状态。因此,如果可能的话,让您的客户端发出主动关闭,这会将 TIME_WAIT 留在客户端而不是服务器上。

请参阅此处:http ://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers.html和http://www.isi.edu/touch/pubs/infocomm99/infocomm99-web/了解详细信息(后者还解释了为什么由于协议设计不考虑 TIME_WAIT 而并非总是可行)。

于 2008-12-03T15:40:34.863 回答
10

Pax 关于 TIME_WAIT 的原因是正确的,以及为什么您应该小心降低默认设置。

更好的解决方案是更改用于套接字原始端的端口号。一旦你这样做了,你就不会真正关心等待单个套接字的时间了。

对于侦听套接字,您可以使用 SO_REUSEADDR 来允许侦听套接字绑定,尽管 TIME_WAIT 套接字位于周围。

于 2008-12-03T14:05:28.003 回答
4

在 Windows 中,您可以通过注册表更改它:

; Set the TIME_WAIT delay to 30 seconds (0x1E)

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP\Parameters]
"TcpTimedWaitDelay"=dword:0000001E
于 2013-03-24T00:47:03.220 回答
2

设置 tcp_reuse 比更改 time_wait 更有用,只要您有参数(内核 3.2 及更高版本,不幸的是,这会取消所有版本的 RHEL 和 XenServer)。

删除该值,特别是对于 VPN 连接的用户,可能会导致在出站连接上不断地重新创建代理隧道。使用低于默认 Linux 配置的默认 Netscaler (XenServer) 配置,Chrome 有时必须重新创建代理隧道多达十几次才能检索一个网页。不重试的应用程序,例如 Maven 和 Eclipse P2,只会失败。

参数的最初动机(避免重复)被一个 TCP RFC 变得多余,该 RFC 指定所有 TCP 请求中包含时间戳。

于 2016-06-02T19:38:10.337 回答
0

我一直在使用具有 20 个线程的测试程序对服务器应用程序(在 linux 上)进行负载测试。

在 959,000 个连接/关闭周期中,我在 TIME_WAIT 中有 44,000 个失败的连接和数千个套接字。

我在关闭调用之前将 SO_LINGER 设置为 0,并且在测试程序的后续运行中没有连接失败,并且 TIME_WAIT 中的套接字少于 20 个。

于 2016-04-28T06:54:48.537 回答
-2

TIME_WAIT 可能不是罪魁祸首。

int listen(int sockfd, int backlog);

根据 Unix Network Programming Volume1,积压被定义为已完成连接队列和未完成连接队列的总和。

假设积压为 5。如果您有 3 个已完成的连接(ESTABLISHED 状态)和 2 个未完成的连接(SYN_RCVD 状态),并且还有另一个带有 SYN 的连接请求。TCP 堆栈只是忽略 SYN 数据包,知道它会在其他时间重新传输。这可能会导致降级。

至少那是我一直在读的。;)

于 2008-12-03T18:04:41.250 回答