Linux – TCP源端口重用(和延迟)

我们有一个应用程序对远程Web服务器/服务进行了大量的调用。 客户端应用程序是Linux上的JBoss / Java(红帽子5),远程服务器是Windows 2008.有一个思科ACE的方式,但没有NAT'ing。

我们注意到,当Linux / JBoss重用一个源端口进行HTTP调用时,我们可以得到“连接被拒绝”。 客户端在几分钟之内重新使用所述源端口。

我在两边运行tcpdump / wireshark时看到的是这样的:

请求#1:源端口6666,目标端口80

客户端 – > Syn Server – > SYN ACK客户端 – > ACK客户端 – > GET /服务器 – >返回数据客户端 – > ACK服务器 – > FIN ACK客户端 – > FIN ACK服务器 – > ACK

请求#2:相同的源和目标端口是成功的。

请求#3:相同的源和目标端口是成功的。

请求#4:相同的源和目标端口,但是这次失败(“拒绝连接”),如下所示:

客户端 – > SYN客户端 – > SYN(重新传输)客户端 – > RST,ACK

服务器同时看到SYN,但从不发送ACK或RST(它从客户端看到RST)。

在做了一些search后,我发现了TCP时间戳的潜在问题。 我们确保ACE让那些通过,我可以validationWindows正在看到他们。 我也看到在服务器/ Windows端的TIME_WAIT状态的连接(但我看到,即使在第一个成功的GET和#2和#3,所有这些都是成功的)。 端口没有打开或在客户端的TIME_WAIT中。

我一直在寻找的一个地方是将Windows端的TcpTimedWaitDelayregistry项减less到30秒。 我还没有做过这个或testing这个,但认为它应该工作,如果我们的问题在那里。

我已经增加了端口在客户端/ Linux端到像15000 – 60000(从默认30000到60000),但无济于事(只希望增加可用的端口将转化为更长的延迟时间由于随机使用源端口)

我觉得奇怪的是,服务器端/ Windows端看到的SYN来通过,但没有响应,让我觉得它认为SYN是从以前的会话或东西。

我不确定我会喜欢这个,但是我想知道是否有一种方法可以告诉Linux不要重复使用源端口,如果它最近被使用的话? 像某种逻辑推迟(如果有的话)?

这并不是说我们的可用端口或任何东西都用完了,但有时候,因为它是随机的,源端口会在几分钟内得到重用,这就是我们遇到的问题。

你们还有其他想法吗?

谢谢!

UPDATE

我在Windows服务器上设置TcpTimedWaitDelay为30秒。 只要在30秒之后重新使用源端口的呼叫就没有问题了。

我相信ACE在某些方面仍然是有责任的,它可能是某种SYN攻击保护(ACE是安全设备),就好像我绕过ACE一样,我没有任何问题。

但是将2MSL设置为30秒似乎已经足够了。

我不太了解Windows套接字循环来回答这个问题,但是我猜测服务器closures了连接,并且套接字处于TIME_WAIT状态,直到它们到期为止,它们不能再次使用。

解决这个问题的“正确”方法是添加更多元组 – 增加客户端上的传出端口(已经完成),在服务器上添加监听端口,将IP别名添加到您的接口,并使应用程序使用这些额外的IP /端口。

一个“不太正确”的方法是减lessTW超时,我认为你正在使用TcpTimedWaitDelay

一个“不是很对,但仍然相当受欢迎”的方式是启用套接字回收,Linux有选项tw_reusetw_recycle ,也许Windows有相同的function。

最后两个选项会破坏TCP RFC。 也许ACE有这个问题吗?