[英]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.