4

我正在设计一个系统,该系统使用 ETL 工具来检索一批数据,即插入/更新/删除一个或多个表,并将它们放在 JMS 主题上,以便稍后由多个客户端处理。现在,关于主题的每条消息都代表一条记录 I/U/D,我们有一条特殊消息来分隔批处理的结束。在单个事务中处理批次很重要,因此由一个特殊的消息分隔一堆消息并不理想:会话发布和接收消息都必须针对多条消息进行设计;批处理分隔符消息是一个混乱的解决方案(每次我们收到一条消息,我们都需要检查它是否是最后一条)并且非常容易出错;系统难以调试和维护;关于该主题的消息数量迅速变得庞大(高达数百万)。

现在,我认为改进架构的下一个自然步骤是将所有记录打包在单个 JMS 消息中,这样当接收到消息时,它包含单个事务,很容易检测到故障,没有“孤儿”关于主题的记录等。我只看到这样做的好处!现在这是我的问题:

  • 创建这样一个打包消息的最佳方法是什么?我认为我的选择是StreamMessageByteMessageObjectMessage。我排除了文本和地图消息,因为第一个将需要文本解析,这会降低性能,我认为第二个似乎并不真正适合该场景。我有点倾向于StreamMessage因为它看起来非常紧凑,尽管它需要大量的工作来编写自定义序列化代码(对于 ByteMessage 来说更糟)。不确定 ObjectMessage,它是如何执行的?是否有开箱即用的解决方案?
  • 每条消息允许的最大大小是多少?它可能是数百 KB 甚至几 MB 的数量级吗?

感谢您的想法!

乔瓦尼

4

2 回答 2

2

您可以使用两个(或更多)队列、相关 ID 和一个消息选择器,而不是使用一条大消息。

排队:

  1. 将通知消息发布到“通知队列”以指示应该开始处理
  2. 将命令消息发布到“命令队列”,相关 ID 设置为通知消息消息 ID(如果队列深度太高,您可以使用多个命令队列)
  3. 提交交易

加工:

  1. 从“通知队列”接收通知消息(例如使用消息驱动 bean)
  2. 使用消息选择器接收和处理来自“命令队列”的所有相关消息
  3. 提交交易
于 2013-03-28T08:26:03.520 回答
1

使用字节(例如 ByteMessage)可能会占用较少的内存。

如果您操作 Java 对象,则可以使用快速且字节有效的序列化/反序列化库,如Kryo

我们很乐意在消息系统的生产环境中使用 Kryo,但您有很多替代品,例如流行的Google Protocol Buffers

于 2013-03-28T05:41:05.837 回答