3

我需要解码以高速率(> 1000 msgs/sec)传入的二进制消息,并使用JAVA将它们存储在数据库中(未决定哪一个)。将有多个 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”是创建一个线程池来处理每条消息还是自己做。我将实施前者并检查性能,看看是否需要改进。我的问题是,nettyApache Mina 是值得考虑的好选择吗?由于这是 POC 工作,我需要快速启动它。

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

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

4

3 回答 3

3

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

我会使用 DataInputStream,除非您确定这不够快。性能影响很小,但在 1000 msg/sec 时不太重要。

我会在消息到达时使用 JDK 对其进行解码。在这种情况下,我还没有找到让事情变得更简单的第三方库。

于 2012-06-14T17:08:39.040 回答
2

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

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

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

于 2012-06-16T08:54:31.457 回答
1

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

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

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

于 2012-06-14T18:27:33.010 回答