tcp_tw_reuse和tcp_tw_recycle:应该使用哪一个(或两个都用)?

71

我有一个网站和应用程序,使用了大量的连接。它通常有约3,000个静态打开的连接,并且在几秒钟的时间内可以接收到5,000到50,000个连接尝试。

由于TIME_WAIT状态套接字,我曾经遇到过无法打开新连接的问题。即使将tcp_fin_timeout设置为低值(1-5),这似乎仍然会导致太多的开销/减速,并且偶尔仍然无法打开新套接字。

我已经查看了tcp_tw_reuse和tcp_tw_recycle,但我不确定哪个是首选项,或者是否可以同时使用它们两个。


4
你已经尝试使用套接字选项SO_REUSEADDR了吗? - SKi
11
“cat /proc/sys/net/ipv4/ip_local_port_range”的输出是什么?如果不是1024到65535之间,您可以使用“echo 1024 65535 > /proc/sys/net/ipv4/ip_local_port_range”来更改它。 - Pablo Castellazzi
4个回答

69
根据Linux文档,您应该使用TCP_TW_REUSE标志来允许在TIME_WAIT状态下重用套接字以进行新连接。当处理许多处于TIME_WAIT状态的短TCP连接的Web服务器时,这似乎是一个不错的选择。
正如此处所述,启用TCP_TW_RECYCLE可能会在使用负载均衡器时引起一些问题...
编辑(添加一些警告;)):
如@raittes的评论所述,“在使用负载均衡器时出现问题”是关于公共面向的服务器。启用回收时,服务器无法区分来自同一NAT设备后面的不同客户端的新传入连接。

7
“使用负载均衡器时出现的问题”是指公共面向服务器。启用回收后,服务器无法将来自同一NAT设备后不同客户端的新连接区分开来。” - raittes
根据Vincent Bernat的帖子(https://vincent.bernat.ch/en/blog/2014-tcp-time-wait-state-linux,也在其他答案中引用),TCP_TW_REUSE仅对出站连接有用,并且对入站连接没有影响。尽管如此,我尚未独立验证此声明。 - Christoph
Christoph,Linux内核文档中没有提到这一点。TIME_WAIT状态仅适用于关闭连接的一方(即“主动关闭”),它高度依赖于协议。对于像原始问题所引用的HTTP协议,它将是服务器端。 - Bernard Rosset

40

实际源代码可以在本文中链接的提交引用中找到。 - Bernard Rosset

0

pevik提到了一篇有趣的博客文章, 在描述所有可用选项时走了额外的路程。

修改内核选项必须被视为最后的选择,通常应该避免,除非你知道自己在做什么...如果是这种情况,你就不会在这里寻求帮助。因此,我建议不要这样做。

我能提供的最合适的建议是指出描述网络连接的部分:四元组(客户端地址客户端端口服务器地址服务器端口)。

如果你可以扩大可用端口池,你将能够接受更多并发连接:

客户端地址和客户端端口无法更改(不在您的控制范围内) 服务器端口:只能通过调整内核参数进行更改:如果您知道需要为系统上的其他进程留出多少端口,则比更改TCP存储桶或重用更不关键。 服务器地址:向主机添加地址并在其中平衡流量:
- 在已经为您的负载大小调整的L4系统后面或直接 - 将您的域名解析为多个IP地址(并希望通过DNS共享负载跨地址)

0
根据VMWare文档,主要区别在于TCP_TW_REUSE仅适用于出站通信。
  • TCP_TW_REUSE使用服务器端时间戳,一旦时间戳大于上次接收到的数据包,服务器就可以将time-wait套接字端口号用于出站通信。使用这些时间戳可以安全地丢弃旧连接的重复数据包或延迟数据包。

  • TCP_TW_RECYCLE也使用相同的服务器端时间戳,但它影响入站和出站连接。当服务器是第一方发起连接关闭时,这很有用。这允许源IP到服务器的新客户端入站连接。由于这种差异,它会导致客户端设备位于NAT设备后面的问题,因为多个设备尝试联系服务器可能无法建立连接,直到Time-Wait状态完全过期。


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