Мой отправитель отправляет 10000 запросов в секунду (или даже больше), но мой ServerSocketChannel способен читать и обрабатывать (в потоке) 8000 запросов (~ appx).Как обслуживать 1000 одновременных соединений с использованием Java NIO
пустышка код выглядит так:
public class NioReceiver {
private int port = -1;
private static String message = null;
public void receive() throws IOException {
// Get the selector
Selector selector = Selector.open();
// Selector is open for making connection
// Get the server socket channel and register using selector
ServerSocketChannel SS = ServerSocketChannel.open();
InetSocketAddress hostAddress = new InetSocketAddress(this.port);
SS.bind(hostAddress);
SS.configureBlocking(false);
int ops = SS.validOps();
SelectionKey selectKy = SS.register(selector, ops, null);
for (;;) {
//Waiting for the select operation...
int noOfKeys = selector.select();
// The Number of selected keys are: noOfKeys
Set selectedKeys = selector.selectedKeys();
Iterator itr = selectedKeys.iterator();
while (itr.hasNext()) {
ByteBuffer buffer = ByteBuffer.allocate(1024 * 60);
SelectionKey ky = (SelectionKey) itr.next();
if (ky.isAcceptable()) {
// The new client connection is accepted
SocketChannel client = SS.accept();
client.configureBlocking(false);
// The new connection is added to a selector
client.register(selector, SelectionKey.OP_READ);
// The new connection is accepted from the client: client
} else if (ky.isReadable()) {
// Data is read from the client
SocketChannel client = (SocketChannel) ky.channel();
String output = null;
buffer.clear();
int charRead = -1;
try {
charRead = client.read(buffer);
} catch (IOException e) {
continue;
}
if (charRead <= 0) {
// client closed
client.close();
} else {
output = new String(buffer.array());
message = output;
try {
new Thread(() -> {
processAndStore(message);
}).start();
} catch (Exception e) {
System.err.println("Thread exception:::" + e.getMessage());
}
} // else if of client.isConnected()
} // else if of ky.isReadable()
itr.remove();
} // end of while loop
} // end of for loop
}
public void processAndStore(String output) {
String exchangeName = null;
String dataLine = null;
String Lines[] = output.split("\r\n");
for (int i = 0; i < Lines.length; i++) {
if (Lines[i].contains("Host: ")) {
exchangeName = Lines[i].substring(6);
}
if (Lines[i].isEmpty()) {
dataLine = Lines[i + 1];
}
}
StringBuffer updatedLastLine = null;
if (dataLine != null) {
if (dataLine.contains("POST")) {
updatedLastLine = new StringBuffer(dataLine.substring(0, dataLine.indexOf("POST")));
} else {
updatedLastLine = new StringBuffer(dataLine);
}
if (!dataLine.equals("")) {
try {
if (updatedLastLine.lastIndexOf("}") != -1) {
updatedLastLine.replace(updatedLastLine.lastIndexOf("}"), updatedLastLine.lastIndexOf("}") + 1, ",\"name\":\"" + exchangeName
+ "\"}");
} else {
return;
}
} catch (StringIndexOutOfBoundsException e) {
System.out.println(updatedLastLine + "::" + dataLine);
System.out.println(e);
}
store(updatedLastLine.toString());
}
}
}
public NioReceiver(int port) {
this.port = port;
}
}
Когда я удаление логики обработки он может получить больше запросов, но не все.
Как я могу улучшить свой код, чтобы получать все входящие запросы 10000s.
Купить более быстрый компьютер? Масштабирование? --- Используйте пул потоков/очередь сообщений вместо создания 1000 потоков для вызова 'processAndStore()'. Запуск потока ** дорого **. Начиная 10000 потоков в секунду? * Yikes! * --- ** Код профиля **, чтобы увидеть, где узкое место, а не гадать, но вот некоторые догадки: 1) Не используйте 'StringBuffer', используйте' StringBuilder'. 2) Не вызывайте 'lastIndexOf ("} ")' три раза. – Andreas
Целью NIO является сокращение количества требуемых потоков. У вас, похоже, нет сообщения. Неясно, что вы спрашиваете. – EJP
Хорошо благодарю вас за своевременные ответы. Между тем, что я сделал, я удалил создание потоков, и производительность немного улучшилась. Более того, я пропустил «NIO» и использовал приемник «netty» и «SimpleChannelInboundHandler» и с той же аппаратной конфигурацией, я получаю почти все запросы. – desaiankitb