改变/ proc / sys / net / ipv4 / tcp_tw_reuse的值是否危险?

我们有几个生产系统最近被转换成虚拟机。 我们的应用程序经常访问MySQL数据库,并为每个查询创build一个连接,查询并断开连接。

这不是查询(我知道)的适当的方式,但我们有我们似乎无法解决的约束。 无论如何,问题是这样的:虽然机器是一个物理主机,程序运行良好。 一旦转换到虚拟机,我们注意到数据库的间歇性连接问题。 有一次,在TIME_WAIT有24000+套接字连接(在物理主机上,我看到的最多的是17000 – 不好,但不会造成问题)。

我想这些连接被重用,以便我们不会看到连接问题,所以:

问题:

可以设置tcp_tw_reuse的值为1吗? 什么是明显的危险? 有什么理由我不应该这样做吗?

另外,还有没有其他办法可以让系统(RHEL / CentOS)阻止如此多的连接进入TIME_WAIT,或者让它们被重用?

最后,改变tcp_tw_recycle会做什么,并会帮助我?

提前,谢谢!

您可以安全地减less时间,但可能会遇到networking丢包或抖动不正常的networking连接问题。 我不会在1秒钟开始调整,从15-30开始,并努力工作。

另外,你真的需要修复你的应用程序。

RFC 1185在3.2节有一个很好的解释:

当一个TCP连接closures时,在TIME-WAIT状态下,延迟2 * MSL会将套接字对连接4分钟(参见[Postel81]的第3.5节)。build立在TCP上的应用程序closures一个连接并打开一个新连接(例如,使用Stream模式的FTP数据传输连接)必须每次select一个新的套接字对,这个延迟有两个不同的目的:

(a) Implement the full-duplex reliable close handshake of TCP. The proper time to delay the final close step is not really related to the MSL; it depends instead upon the RTO for the FIN segments and therefore upon the RTT of the path.* Although there is no formal upper-bound on RTT, common network engineering practice makes an RTT greater than 1 minute very unlikely. Thus, the 4 minute delay in TIME-WAIT state works satisfactorily to provide a reliable full-duplex TCP close. Note again that this is independent of MSL enforcement and network speed. The TIME-WAIT state could cause an indirect performance problem if an application needed to repeatedly close one connection and open another at a very high frequency, since the number of available TCP ports on a host is less than 2**16. However, high network speeds are not the major contributor to this problem; the RTT is the limiting factor in how quickly connections can be opened and closed. Therefore, this problem will no worse at high transfer speeds. (b) Allow old duplicate segements to expire. Suppose that a host keeps a cache of the last timestamp received from each remote host. This can be used to reject old duplicate segments from earlier incarnations of the 

*注意:可以认为发送FIN的那一方知道它需要什么程度的可靠性,因此它应该能够确定FIN的接收者的TIME-WAIT延迟的长度。 这可以通过FIN段中适当的TCP选项来完成。

  connection, if the timestamp clock can be guaranteed to have ticked at least once since the old conennection was open. This requires that the TIME-WAIT delay plus the RTT together must be at least one tick of the sender's timestamp clock. Note that this is a variant on the mechanism proposed by Garlick, Rom, and Postel (see the appendix), which required each host to maintain connection records containing the highest sequence numbers on every connection. Using timestamps instead, it is only necessary to keep one quantity per remote host, regardless of the number of simultaneous connections to that host. 

这不能回答你的问题(而且这个问题已经晚了18个月),但是提出了另一种使你的旧版应用重用端口的方法:

在系统上设置tcp_tw_reuse (或tcp_tw_recycle )的一个有用的替代方法是将共享库(使用LD_PRELOAD )插入到您的应用程序中; 那么该库可以允许重用该端口。 这使得您的传统应用程序允许重复使用端口,而无需在系统上强制执行所有应用程序(不需要修改您的应用程序),从而限制了您调整的影响。 例如,

  LD_PRELOAD=/opt/local/lib/libreuse.so ./legacy_app 

这个共享库应该拦截socket()调用,调用实际的套接字(),并在返回的套接字上设置SO_REUSEADDR和/或SO_REUSEPORT。 看一下http://libkeepalive.sourceforge.net如何做到这一点(这将打开keepalives,但打开SO_REUSEPORT是非常相似的)。 如果您的不良行为的旧版应用程序使用IPv6,请记得更改libkeepalive.c第55行

  if((domain == PF_INET) && (type == SOCK_STREAM)) { 

  if(((domain == PF_INET) || (domain == PF_INET6)) && (type == SOCK_STREAM)) { 

如果你卡住了,给我发电子邮件,我会写代码并发送给你。

我认为把这个值改为1是很好的。更合适的方法可能是使用这个命令:

 [root@server]# sysctl -w net.ipv4.tcp_tw_reuse=1 

没有明显的危险,我知道,但快速谷歌search产生这个链接 ,确认tcp_tw_reuse是比tcp_tw_recycle更好的select,但应谨慎使用,无论。

如果处于TIME WAIT状态,则无法重新使用连接。 如果在应用程序和MySQL之间的networking上没有丢包,则可以降低超时。

但是,最好的解决scheme是使用持久连接到数据库和连接池。