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

时间:2011-11-29 19:56:56

标签: java networking nio

我正在处理涉及从套接字交易报价中读取的任务,我需要实现最小延迟和高吞吐量。

我从最简单的可能的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和disruptor框架,他们在单个线程上实现了6M事务。

2 个答案:

答案 0 :(得分:4)

使用Disruptor和其他方法可以获得更高的效果。很大程度上取决于消息的大小和复杂性(以及您对消息的处理方式!!)

如果要使用ByteBuffer序列化/反序列化,请使用putXxxx和getXxxx方法。为了简化此过程,我建议先将每条消息的长度放在一起,以便在尝试解析之前检查是否有完整的消息。

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

答案 1 :(得分:1)

假设您可以调整解析器API以接受(byte[] buffer, int offset, int length)作为参数,您只需将(bb.array(), 0, bb.limit())作为参数传递,而不必在每次读取时创建new byte[]。然而,这不太可能是决定利率的步骤。