0

当我的客户端连接到服务器时,我遇到了这个“java.net.ConnectException:连接超时”异常。

它们都在同一个 LAN 中,在同一个集群中,它们之间没有防火墙。此外,它们对多达 1000 个客户也能正常工作,或多或少。当我启动 1200 个客户端时,其中许多(数百个)在连接到服务器时超时。每个客户端不断向服务器发送请求,这会在服务器上施加 cpu 负载,这在几个线程中约为 100%。

如何在不添加服务器或增加超时的情况下避免此问题?我也做过sudo sysctl -w net.core.somaxconn=2048,没用。

我正在使用 NIO 连接到服务器:

SocketChannel serverChannel = SocketChannel.open();
serverChannel.connect(new InetSocketAddress(serverAddr, serverPort));
serverObjectOutStream = new ObjectOutputStream(Channels.newOutputStream(serverChannel));
serverObjectInStream  = new ObjectInputStream (Channels.newInputStream (serverChannel));

至于服务器:

while (running) {
   SocketChannel newClientChannel = serverSocketChannel.accept();
   ObjectInput  cliInput  = new ObjectInputStream (Channels.newInputStream (newClientChannel));
   ObjectOutput cliOutput = new ObjectOutputStream(Channels.newOutputStream(newClientChannel));
   // receive client's id and put it in a hashtable of id -> in,out channels
   // acknowledge the client
}
4

2 回答 2

0

检查网络负载。所有这些客户端的 NIC 使用率是否达到 100%?此外,100% 的 CPU 可能是一个瓶颈。看一下这个。您没有提供太多细节,但还要检查您的操作系统是否需要调整。

如果排除硬件,是时候检查软件了。

基本上,您所拥有的是 C10K 问题。这是一个非常好的关于它的读物(带有更多读物的链接) http://www.kegel.com/c10k.html

于 2013-09-16T18:20:27.300 回答
0

显然,原因是服务器没有足够快地接受新连接,因为它处理了每个连接,只有在接受下一个连接之后。

这就是我最终解决它的方法,以便服务器可以在接受新客户端的同时做一些事情,防止它们超时:

BlockingQueue acceptedConnections = new LinkedBlockingQueue<SocketChannel>();

// Thread 1 (connection acceptor):
public void run() {
   while (running) {         
      SocketChannel newClientChannel = serverSocketChannel.accept();
      acceptedConnections.add(newClientChannel);         
   }
}

// Thread 2 (connection handler):
public void run() {
   while (running) {               
      SocketChannel newConn = acceptedConnections.take();
      // handle new connection, while still accepting others
   }
}  
于 2013-09-16T22:22:56.563 回答