简体   繁体   English

如何使用Java NIO从套接字高效读取

[英]How to read efficiently from socket using Java NIO

I am working on task involving reading from the socket trading quotes and I need to achieve minimum latency and high throughput. 我正在处理涉及从套接字交易报价中读取的任务,我需要实现最小延迟和高吞吐量。

I started with the simpliest possible java nio prototype like this 我从这样的最简单的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) {    
}

I guess it is lame to create byte[] array every time, but due to the lack of knowledge I dont know how to parse ByteBuffer ( because I need to unmarshall byte protocol into messages and pass them into business logic). 我猜每次创建byte []数组都是很me脚,但是由于缺乏知识,我不知道如何解析ByteBuffer(因为我需要将字节协议解组到消息中并将它们传递到业务逻辑中)。 Can you recommend how to avoid mass garbage creation? 您能推荐如何避免大量垃圾的产生吗?

Also I would like to ask about best practices how to organize socket reading with low latency and high throughput? 我也想问一下最佳实践,如何组织具有低延迟和高吞吐量的套接字读取? I read about LMAX and disruptor framework and they achieved 6M transactions on the single thread. 我了解了LMAX和中断框架,它们在单线程上实现了600万笔交易。

You can achieve higher than that with Disruptor and other methods. 您可以使用Disruptor和其他方法实现更高的目标。 A lot depends on the size and complexity of message (as well as what you do with the message !!) 很大程度上取决于消息的大小和复杂性(以及您对消息的处理方式!)

If you want to serialize/deserialze with ByteBuffer, use the putXxxx and getXxxx methods. 如果要使用ByteBuffer进行序列化/反序列化,请使用putXxxx和getXxxx方法。 To make this process easier, I suggest putting the length of each message first so you can check you have a full message before attempting to parse it. 为了简化此过程,建议您将每条消息的长度放在首位,以便您在尝试解析消息之前检查是否有完整的消息。

You might find this presentation interesting http://vanillajava.blogspot.com/2011/11/low-latency-slides.html 您可能会发现此演示文稿很有趣http://vanillajava.blogspot.com/2011/11/low-latency-slides.html

Assuming you can adapt your parser API to accept (byte[] buffer, int offset, int length) as arguments, you can just pass (bb.array(), 0, bb.limit()) as parameters and not have to create the new byte[] at all per read. 假设您可以使解析器API适应以接受(byte[] buffer, int offset, int length)作为参数,则只需传递(bb.array(), 0, bb.limit())作为参数,而不必创建每次读取时都使用new byte[] However this isn't likely to be the rate-determining step. 但是,这不太可能是速率确定步骤。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM