设置TIME_WAIT TCP


70

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

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

我不是“网络专家”,对这些事情了解甚少。我需要该链接文章中的很多内容,但要“简化”一下。

  • 我想我理解为什么TIME_WAIT不能将值设置为0,但是可以安全地将其设置为5吗?那10点呢?是什么确定该值的“安全”设置?
  • 为什么此值的默认值为60?我猜想比我聪明的人有充分的理由将其选为合理的默认值。
  • 关于覆盖此值的潜在风险和收益,我还应该了解什么?

你也不想将其设置为过高:stackoverflow.com/questions/1803566/...
Pacerier

Answers:


97

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

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

因此,通常将TIME_WAIT时间设置为使数据包最大寿命加倍。此值是您的数据包在网络丢弃之前可以达到的最长期限。

这样可以保证在允许您使用相同的元组创建连接之前,属于该元组的先前版本的所有数据包都将被丢弃。

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


1
如何确定“最长封包使用期限”?这是操作系统,网络上的某项设置还是软件设置?顺便说一句,“生成”大多数连接的代码是我们没有源的第三方平台。感谢您的大力响应!
文妮

5
它的真实名称是最大段生存期MSL。不知道您是否可以在Windows中更改此设置,或者是否可以更改-它是根据网络特性进行设置的。我认为Windows将其设置为120s。所有TCP参数都在HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Services \ Tcpip \ Parameters中。
paxdiablo

Not sure you can change this in Windows or even if you should - it's meant to be set based on network characteristics. Windows sets it to 120s, I think. ☹你绝对可以改变它的Linux和120太长。我尚未测试确认,但是看起来如此长时间的延迟使大多数路由器上的P2P陷入了不必要的困境。
Synetech

@Synetech,它仅在您循环进行大量会话时才会引起问题。否则,应在超时时进行会话清除。我相信即使是洪流也能使会话保持一段时间,尽管有可能,但是如果可能的话,可以重用它们,但这当然取决于客户端。
paxdiablo

@paxdiablo,是的,应该。我取代了我好老DI-524以“更新,更好” DIR-625是我做的一样,但自那以后,每当我只是打开一个BT客户端,我的连接模具(无HTTP,NTP,平,无)。除了路由器之外,其他所有内容都相同。我检查了TCPView,发现torrent客户端有很多缠绵的连接。几乎立即关闭它,我可以再次冲浪,因此显然路由器不堪重负。减少延迟有帮助(我已经减少了#connections的很多)。(此外,即使NTP也不起作用,Chrome也会打开无数的连接。)
Synetech

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而使之并非总是可能的)。


2
好的一点是,服务器仍将必须等待其FIN发出的ACK,但这将花费更少的时间。对于发起方来说,关闭会话也是一种好习惯,因为只有会话方通常知道何时完成。
paxdiablo


10

Pax关于TIME_WAIT的原因是正确的,并且在降低默认设置时应格外小心。

更好的解决方案是更改用于套接字原始端的端口号。完成此操作后,您将不再真正在意等待单个套接字的时间。

对于侦听套接字,您可以使用SO_REUSEADDR来允许侦听套接字绑定,尽管TIME_WAIT套接字仍然存在。


14
我将以“ Pax是正确的”短语开头的所有答案都赞成。:-)
paxdiablo

4
对于具有成千上万个活动套接字的非常活跃的计算机,实际上可以在TIME_WAIT中捆绑所有临时端口。一旦发生这种情况,您将无法打开任何其他连接,直到某些套接字完成等待。减少TIME_WAIT持续时间会很有帮助。正如Len Holgate所提到的,如果可能的话,最好让客户端启动主动关闭,因为这完全消除了服务器的TIME_WAIT职责。
山姆·汉斯

1
默认情况下,原始端口号会自动更改,这对服务器的TIME_WAIT状态没有帮助。正确的解决方案是确保客户端首先关闭。
user207421 '17

4

在Windows中,你可以改变通过注册表

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

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP\Parameters]
"TcpTimedWaitDelay"=dword:0000001E

6
设置tcp_fin_timeout不会影响time_wait-这是一个常见的误解。这是完全不同的事情(显然是FIN超时)。许多指南等都指向此设置,但它们是错误的。查看tcp.h,您将看到它是硬编码的(Linux)。
mcauth 2014年

2

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

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

该参数的原始动机(避免重复)由指定所有时间戳记包含时间戳的TCP RFC冗余化。


0

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

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

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


2
而且您还冒着丢失数据的风险。这不是正确的解决方案。SO_LINGER不是一件容易的事。正确的解决方案是确保客户端首先关闭,通常是通过在客户端建立连接池并编写服务器来处理每个连接的多个请求。实际上就像HTTP 1.1。
user207421 '17

我的回答应该更加清楚。我并不主张将延迟时间设置为0,只是指出我在Windows上观察到的问题。在linux上没有发生此问题。因此,它取决于系统,并且可能取决于激活的系统设置。
迈克尔·泰勒

它不依赖于系统。这样重置套接字会丢失所有正在传输的数据。
user207421'9

-2

TIME_WAIT可能不是罪魁祸首。

int listen(int sockfd, int backlog);

根据Unix网络编程卷1,积压定义为已完成连接队列和未完成连接队列的总和。

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

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


我敢肯定,积压工作仅用于尚未建立的连接。一旦拥有,就将其从队列中删除;它们只会阻塞更多的传入连接,直到(SYN,SYN / ACK,ACK)握手完成为止,基本上是服务器从accept()返回之后。
paxdiablo

1
(-1)不,侦听积压仅用于未完全建立的连接;也就是说,它们已经到达TCP / IP堆栈,但尚未被“接受”。如果侦听积压太小,则如果连接进入的速度快于接受连接的速度,则服务器将拒绝连接。
Len Holgate

2
轻微的误会。“完成的连接队列。此队列包含每个完成三向握手的连接的条目。套接字处于ESTABLISHED状态。每次对accept()的调用都将删除队列的最前面的条目。” sean.de/Solaris/soltune.html
yogman

1
@LenHolgate仍可以完全建立未被接受的连接,并且此类连接进入积压队列。还有其他队列用于不完整的连接。是拒绝还是忽略将导致积压的溢出的传入连接取决于系统:Windows拒绝,Unix等忽略。
user207421 '17
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.