Java 有许多客户端连接的服务器没有瓶颈
Java Server having many clients connect without bottlenecking
所以我想做的是有一个套接字从客户端接收输入,将客户端放入队列,然后 return 当我的算法 return是真的。
这个队列应该同时支持几百个客户端,但同时不会限制服务器,所以它实际上可以做它应该做的事情。
这是我目前拥有的:
private static final int PORT = 25566;
private static final int THREADS = 4;
private ExecutorService service;
public void init() throws IOException, IllegalStateException {
ServerSocket serverSocket;
serverSocket = new ServerSocket(PORT);
service = Executors.newCachedThreadPool();
Socket socket;
while(true) {
socket = serverSocket.accept();
System.out.println
("Connection established with " + socket.getInetAddress().toString());
service.execute(() -> {
Scanner scanner = null;
PrintWriter output = null;
String line = null;
try {
scanner = new Scanner(new InputStreamReader(socket.getInputStream()));
output = new PrintWriter(socket.getOutputStream());
} catch(IOException e) {
e.printStackTrace();
}
try {
if (scanner == null || output == null)
throw new IllegalStateException("Scanner/PrintWriter is " + "null!");
line = scanner.nextLine();
while (line.compareTo("QUIT") != 0) {
/* This is where input comes in, queue for the algorithm,
algorithm happens then returns appropriate values */
output.flush();
line = scanner.nextLine();
}
} finally {
try {
System.out.println
("Closing connection with " + socket.getInetAddress().toString());
if(scanner != null) {
scanner.close();
}
if(output != null) {
output.close();
}
socket.close();
} catch(IOException e) {
e.printStackTrace();
}
}
});
}
}
现在我认为这会发生什么,如果队列确实达到足够高的水平,我的线程池将完全成为服务器的瓶颈,因为所有线程都被用于处理队列中的客户端,并且算法处理不足。
编辑:经过一系列测试后,我认为如果在算法中它 returns 值然后断开连接,而不是等待用户响应,而是让用户客户端在某些条件满足后重新连接,它就会成功遇见了
除非您的机器受限,否则您的瓶颈不太可能是处理能力。更有可能发生的是线程池中的所有线程都被消耗并最终等待来自客户端的输入。您的设计一次只能处理与池中线程一样多的客户端。
对于几百个客户端,您可以考虑简单地为每个客户端创建一个线程。可支持的线程数量的限制资源通常是每个线程所需的堆栈内存,而不是处理能力;根据个人经验,对于内存充足的现代机器,一千个线程不是问题。可能有一个操作系统参数限制了您可能需要调整的线程数。
如果您需要处理大量客户端,您可以将代码设置为轮询套接字以获取可用输入,并仅对那些有输入要处理的套接字进行处理。
所以我想做的是有一个套接字从客户端接收输入,将客户端放入队列,然后 return 当我的算法 return是真的。
这个队列应该同时支持几百个客户端,但同时不会限制服务器,所以它实际上可以做它应该做的事情。
这是我目前拥有的:
private static final int PORT = 25566;
private static final int THREADS = 4;
private ExecutorService service;
public void init() throws IOException, IllegalStateException {
ServerSocket serverSocket;
serverSocket = new ServerSocket(PORT);
service = Executors.newCachedThreadPool();
Socket socket;
while(true) {
socket = serverSocket.accept();
System.out.println
("Connection established with " + socket.getInetAddress().toString());
service.execute(() -> {
Scanner scanner = null;
PrintWriter output = null;
String line = null;
try {
scanner = new Scanner(new InputStreamReader(socket.getInputStream()));
output = new PrintWriter(socket.getOutputStream());
} catch(IOException e) {
e.printStackTrace();
}
try {
if (scanner == null || output == null)
throw new IllegalStateException("Scanner/PrintWriter is " + "null!");
line = scanner.nextLine();
while (line.compareTo("QUIT") != 0) {
/* This is where input comes in, queue for the algorithm,
algorithm happens then returns appropriate values */
output.flush();
line = scanner.nextLine();
}
} finally {
try {
System.out.println
("Closing connection with " + socket.getInetAddress().toString());
if(scanner != null) {
scanner.close();
}
if(output != null) {
output.close();
}
socket.close();
} catch(IOException e) {
e.printStackTrace();
}
}
});
}
}
现在我认为这会发生什么,如果队列确实达到足够高的水平,我的线程池将完全成为服务器的瓶颈,因为所有线程都被用于处理队列中的客户端,并且算法处理不足。
编辑:经过一系列测试后,我认为如果在算法中它 returns 值然后断开连接,而不是等待用户响应,而是让用户客户端在某些条件满足后重新连接,它就会成功遇见了
除非您的机器受限,否则您的瓶颈不太可能是处理能力。更有可能发生的是线程池中的所有线程都被消耗并最终等待来自客户端的输入。您的设计一次只能处理与池中线程一样多的客户端。
对于几百个客户端,您可以考虑简单地为每个客户端创建一个线程。可支持的线程数量的限制资源通常是每个线程所需的堆栈内存,而不是处理能力;根据个人经验,对于内存充足的现代机器,一千个线程不是问题。可能有一个操作系统参数限制了您可能需要调整的线程数。
如果您需要处理大量客户端,您可以将代码设置为轮询套接字以获取可用输入,并仅对那些有输入要处理的套接字进行处理。