Как эффективно читать из сокета с помощью Java NIO - PullRequest
2 голосов
/ 29 ноября 2011

Я работаю над задачей, связанной с чтением из котировок сокетов, и мне нужно добиться минимальной задержки и высокой пропускной способности.

Я начал с самого простого прототипа java nio, подобного этому

ByteBuffer buf = ByteBuffer.allocateDirect(BUFFER_SIZE);
try {
       buf.clear();
       int numBytesRead = socketChannel.read(buf);

       if (numBytesRead == -1) {  
           socketChannel.close();
       } else {
           buf.flip();
           byte[] byteArrived = new byte[buf.remaining];
           buf.get(byteArrived,0,byteArrived.length);
           // here we send byteArrived to the parser
       }
   } catch (IOException e) {    
}

Полагаю, что каждый раз создавать массив byte [] глупо, но из-за недостатка знаний я не знаю, как анализировать ByteBuffer (поскольку мне нужно разобрать протокол байтов в сообщениях и передать их в бизнес-логику). Можете ли вы порекомендовать, как избежать массового создания мусора?

Также я хотел бы спросить о передовых практиках, как организовать чтение сокетов с низкой задержкой и высокой пропускной способностью? Я читал о LMAX и инфраструктуре прерывателя, и они достигли 6 миллионов транзакций в одном потоке.

Ответы [ 2 ]

4 голосов
/ 30 ноября 2011

Вы можете достичь более высоких результатов, чем Disruptor и другими методами. Многое зависит от размера и сложности сообщения (а также от того, что вы делаете с сообщением !!)

Если вы хотите сериализовать / десериализовать с помощью ByteBuffer, используйте методы putXxxx и getXxxx. Чтобы упростить этот процесс, я предлагаю сначала указать длину каждого сообщения, чтобы вы могли проверить, что у вас есть полное сообщение, прежде чем пытаться его проанализировать.

Вы могли бы найти эту презентацию интересной http://vanillajava.blogspot.com/2011/11/low-latency-slides.html

1 голос
/ 30 ноября 2011

Предполагая, что вы можете адаптировать API вашего синтаксического анализатора для приема (byte[] buffer, int offset, int length) в качестве аргументов, вы можете просто передать (bb.array(), 0, bb.limit()) в качестве параметров и не создавать вообще new byte[] за чтение.Однако это вряд ли будет шагом, определяющим скорость.

...