Java Server to Handle More Concurrent Connections
The following program can handle almost 65000 (65K) request with a single instance.
/**
* This server socket program has been created to test the programe with -client and -server JVM parameters.
*/
package sockets;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author prabhu kvn
*
*/
public class ServerSocketDemoWithBlockingQueue {
Logger logger = LoggerFactory.getLogger(this.getClass().getName());
/**
* A blocking queue to handle connections. this can hold up to one lakh sockets
*/
/**
* Default values
*/
private int queueLength = 10000;
int serverThreadCount = 1;
BlockingQueue<Socket> queue = new LinkedBlockingQueue<>(queueLength);
/**
* Default Constructor
*/
public ServerSocketDemoWithBlockingQueue() {
}
/**
* Default Constructor
*/
public ServerSocketDemoWithBlockingQueue(int serverThreadCount, int queueLength) {
this.serverThreadCount = serverThreadCount;
this.queueLength = queueLength;
this.queue = new LinkedBlockingQueue<>(queueLength);
}
/**
* Entry point for server start up
*
* @param args
*/
public static void main(String[] args) {
ServerSocketDemoWithBlockingQueue demo = new ServerSocketDemoWithBlockingQueue();
demo.startServer();
}
/**
* Starting the server to handle asynch connections
*/
private void startServer() {
logger.info("Starting the server with {} threads and queue size {}", serverThreadCount, queueLength);
ExecutorService service = Executors.newFixedThreadPool(serverThreadCount);
for (int i = 0; i < serverThreadCount; i++) {
service.submit(new ServerProcessing(queue));
}
ServerSocket serverSocket = null;
try {
// create the server socket
serverSocket = new ServerSocket(8181, 100000);
while (true) {
Socket socket = serverSocket.accept();
try {
queue.put(socket);
} catch (InterruptedException e) {
logger.error("Problem in accepting new connections : {}", e);
e.printStackTrace();
}
}
} catch (IOException e) {
logger.error("Problem in creating server socket {}", e);
e.printStackTrace();
} finally {
if (null != serverSocket) {
try {
serverSocket.close();
logger.info("Server Socket closed Successfully.");
} catch (IOException e) {
logger.error("Problem in closing server socket.");
e.printStackTrace();
}
}
}
}
}
/**
* Processing class
*
* @author prabhukvn
*
*/
class ServerProcessing extends Thread {
BlockingQueue<Socket> queue;
volatile int counter = 0;
public ServerProcessing(BlockingQueue<Socket> queue) {
this.queue = queue;
}
@Override
public void run() {
while (true) {
try {
process(queue.take());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* Execute the actual work.F
* @param socket
* @return
* @throws IOException
* @throws SocketException
* @throws InterruptedException
*/
private int process(Socket socket) throws IOException, SocketException, InterruptedException {
System.out.println("Server Socket:" + socket);
OutputStream out = socket.getOutputStream();
out.write(("Request received" + counter).getBytes());
counter++;
socket.setKeepAlive(true);
// Thread.sleep(1000);
// allow client to close the connection
socket.close();
return counter;
}
}