使用java解码二进制消息

时间:2012-06-14 17:02:14

标签: java binary decoding

我需要解码以高速率(> 1000 msgs / sec)发送的二进制消息,并使用 JAVA 将它们存储在DB(未决定哪一个)中。将有多个TCP连接进入此服务器,每个连接都有自己的二进制数据流,需要进行处理。

消息不会被任何“标志”分开 消息的开头有一个4字节长的字段。它后面是一个固定的标题。

消息的有效载荷将依次是多个消息,每个消息具有固定的头部,然后是位掩码(32位),其确定存在哪些其他字段。每个位掩码字段是32位,位32-30(MSB-32 / Big endian)指定每个可选字段的长度。所有其他位(29-1),如果“ON”表示该字段存在于消息中。

例如,如果位32-30是100,并且位1是“1”,则字段XXX跟随位掩码字段并且它是4字节长。如果位2为“0”,则消息中不存在字段YYY,依此类推。 存在多个位掩码字段(可选)但受最大数量限制。 我是java(c / C ++背景)的新手,所以问题可能......

1)我正在考虑以常规方式设计应用程序“主”线程接收连接并创建“工作线程A”来处理该套接字上的消息。我正在考虑让配置文件驱动“workerThread A”是否创建了一个用于处理每条消息的threadPool,或者是自己做的。我将实现前者并检查性能,看看是否需要改进。 我的问题是, netty Apache Mina需要考虑的好选项?由于它是POC的努力,我需要快速启动它。

2)我想过使用nio - SocketChannel和ByteBuffer。但似乎我无法从套接字读取指定数量的字节?我认为“readInt()”更容易获得长度然后从套接字读取“长度”字节数以获得完整的一条消息然后解析它。 DataInputStream是否更好用?使用oio vs nio会对性能产生什么影响?

3)我应该查看任何框架来解码消息吗?我稍微查看了Google协议缓冲区,但它似乎不支持解码位掩码字段。

3 个答案:

答案 0 :(得分:3)

我会为每个连接创建一个工作线程。

我会使用DataInputStream,除非你确定这不够快。性能影响很小,但不太可能达到1000 msg / sec。

我会在使用JDK到达时解码消息。在这种情况下,我没有找到第三方库来简化事情。

答案 1 :(得分:2)

在您的情况下,Apache MINA是一个非常好的选择。 Mina管理多个会话非常好,并且非常可扩展。我们已经将它用于非常相似的情况,到目前为止我们对它非常满意。

我们使用MINA开发了一个网关,它接收来自数千个gsm设备的二进制消息,对其进行解码并将其存储到数据库中。我们在具有Core2 Duo,4 GB RAM的服务器上连续发送数据超过2000个并发会话,对我们的网关进行负载测试。

您可以非常干净地使用Codec Filters将解码器和编码器插入其中。文档也很合理,您可以使用基本的JAVA知识轻松jump start

答案 2 :(得分:1)

我会选择NIO和Selector模型。这是您可以阅读的article(旧的但仍然相关)。

如果您想实现超低延迟,那么您应该考虑合并可以重用的对象而不是创建新对象。 GC不适合低延迟应用。

最后我会尝试使用Google提供的Protocol Buffers,因为它们非常高效且易于使用多种语言。