我们遇到了一个问题,当相对较少的节点(16到24个,但我们将来需要处理更多)试图同时连接时,我们到套接字服务器的传入客户端套接字连接被拒绝。
一些细节:
- 服务器运行在Windows 2008或7上
- 我们的主服务器是使用ServerSocket用Java编写的
- 客户端也是在我们数据中心的网格节点上运行的Windows
当我们尝试在网格上进行测试运行时,客户端节点会尝试连接到服务器并发送40-100K数据包,然后断开连接。使用16到24个节点,我们开始看到客户端连接无法连接到服务器的问题。考虑到这种设置,我们试图同时处理最多16-24个客户端连接和故障,这对我们来说似乎根本不正确。
主服务器循环正在侦听常规SocketServer,当它获得连接时,它会生成一个新的线程来处理连接,并立即返回侦听套接字。我们还有一个伪python服务器,它只读取并丢弃传入的数据,还有一个C++服务器,它在转储数据之前记录数据,这两个服务器都遇到了同样的问题,即客户端无法连接,在故障开始之前成功的客户端连接数量略有变化。这让我们相信,在这个问题上,任何特定的服务器都没有故障,而且可能是环境问题。
我们最初的想法是增加套接字上的TCP积压。即使推到很高的水平,这也没有缓解问题。Java SocketServer的默认值是50,比我们能够处理的要低得多。
我们在同一子网上的机器之间运行了测试,并禁用了机器上的所有本地防火墙,以防FW对我们与服务器的连接进行速率限制;没有成功。
我们已经在运行服务器的Windows机器上尝试了一些网络调整:
- 减少TimedWaitDelay,但没有效果(在我的Python测试中,它不应该这样做,因为该测试只运行几毫秒)
- 将MaxUserPort增加到一个大值,大约65000,但没有效果(这很奇怪,因为我的Python测试只发送240条消息,所以我甚至应该接近这种类型的限制)
- 将TcpNumConnection增加到一个大值(记不清确切的数字)。同样,我们一次的连接不应该超过24个,所以这不能是一个限制
- 启动"动态积压"功能,允许消息积压动态增加。我认为我们将最大连接设置为2000,最小连接设置为1000,但没有效果。同样,Python的连接不应该超过240个,所以我们甚至不应该激活动态囤积
- 除了上述禁用Windows"自动调谐"TCP端口。同样,没有效果
我的感觉是,Windows在某种程度上限制了入站连接的数量,但我们不确定该修改什么来允许更多的连接。网络上的代理限制连接速率的想法似乎也不是真的。我们非常怀疑同时连接的数量是否会使物理GB网络过载。
我们被难住了。有没有其他人经历过这样的问题并找到了解决方案?
我会检查有多少连接处于TCP连接的TIME_WAIT状态。我见过这种类型的问题,因为许多连接被打开/关闭,导致TIME_WAIT导致套接字耗尽。要进行检查,请运行:
众所周知,netstat -a
IIS会处理大量并发传入连接,远远超过您所经历的限制,这使得环境不太可能成为一个来源。
如果正如您所指出的,增加TCP积压并不能改善这种情况,那么问题实际上就出在accept()行为上。您没有指示客户端是否收到各种错误或一致的错误。超时会支持这一点,而拒绝则表明积压工作处理得不够快。
您是否能够尝试将应用程序原型化为ASPX主机以更好地理解问题?
很可能您受到操作系统的限制;您在系统日志中看到4226错误消息了吗?
Windows将并发连接尝试的次数限制为(我认为)每秒10个连接-具体取决于操作系统版本(服务器版本的值最高可达50)
为了消除这种情况,你有两种可能性:
-
使用十六进制编辑器直接编辑system32/drivers中的tcpip.sys-开玩笑:)
-
尝试编辑[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Lanmanserver\Parameters\MaxMpxCt(默认值=10个命令)条目。
如果您使用的版本不允许设置该参数,您也可以尝试此修补程序。
您还可以尝试各种方法,如操作系统使用的最大TCB数量、动态端口分配的端口范围等,尽管这些值足够高,可以满足您的需求。