1

ActiveMQ 消息组是跨多个消费者进行负载平衡的绝佳功能。简而言之:根据嵌入在消息中的组标识符(JMSXGroupID),消息流被划分为单个队列的多个消费者。(因此,消费者 1 将获得所有带有 的消息JMSXGroupID = a,消费者 2 将获得带有 的所有消息JMSXGroupID = b,依此类推。)

现在,假设您有 2 个队列:AB,并假设JMSXGroupID在流经两个队列的消息中使用了一致的 s 分类法。代理在队列中选择的消费者是否会是代理JMSXGroupID = ABC在队列中选择A的同一连接中的消费者?JMSXGroupID = ABCB

我怀疑这个问题的答案是“不”。有太多变量在起作用:如果代理选择的消费者A没有对应的消费者会发生什么B?如果代理选择的消费者A多个对应的消费者,会发生B什么?在这些情况下,没有明显的正确答案。

但是,我们可以模拟这种行为吗?例如,复合目的地上的消费者可能是一个可行的解决方案——确保所有消费者都在复合目的地上AB在复合目的地上消费,A,B并且您可能正在开展业务——但 ActiveMQ 似乎不支持从复合目的地消费。

我发现的唯一解决方案是简单地将消息推送到一个队列上——称之为——A并在其上拥有一个独占消费者。您现在必须区分“ messages”和“ messages”,但您可以使用标题轻松做到这一点。BABAB

然而,这个解决方案闻起来很有趣。(您现在必须假设生产者会尽职尽责地将特殊标头应用于他们的消息,或修改您的有效负载。)是否有一种解决方案可以确保消费者跨越两个单独的队列AB始终位于同一个连接上?

4

1 回答 1

1

正如您正确计算的那样,消息组仅适用于单个队列。多个队列之间没有协调。

通常,当您使用消息组时,您不仅要保证消息的顺序,而且要保证消息的顺序不仅是传递,而且是处理——也就是说,特定实体的所有事件都是按顺序处理的。魔鬼总是在你的用例的细节中,但是将所有相关的消息放到一个队列中会给你你想要的结果。为了以不同的方式处理它们,您需要将某种多路复用逻辑放入您的消费者中,以根据消息有效负载做出决定 - 正如您所说的那样,众所周知的标头是解决方案的良好候选者。

为了绕过确保客户端显式设置它的先决条件,您可以做的是编写一个代表您执行此操作的 Camel 路由逻辑 - 这仅适用于代理:添加到 ActiveMQ 5.9 的组件。这个想法是生产者看到两个单独的队列 - A & B;当消息被放入时,路由逻辑将从这些队列中读取,适当地设置标题,然后将它们重新路由到C。路由逻辑实际上是一个拦截器。

<route id="ConflateA">
  <from uri="broker:queue:A"/>
  <setHeader headerName="OriginalMessageSource">
    <constant>A</constant>
  </setHeader>
  <to uri="broker:queue:C"/>
</route>

然后,您可以在多路复用逻辑中使用OriginalMessageSource标头。

于 2014-01-09T11:25:26.143 回答