我的客户端在连接服务器时遇到“java.net.ConnectException:Connection timed out”异常。
他们都在相同的局域网中,在同一个集群中,它们之间没有防火墙。此外,他们或多或少地工作了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
}
答案 0 :(得分:0)
检查网络负载。您的NIC在所有这些客户端的使用率是否达到100%?此外,100%的CPU可能是一个瓶颈。看一下这个。您没有提供太多细节,但也检查您是否需要调整操作系统。
如果您排除硬件,则需要检查软件。
基本上,你所拥有的是C10K问题。 这是一个非常好的阅读(链接到更多读取) http://www.kegel.com/c10k.html
答案 1 :(得分: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
}
}