跨多个队列的 ActiveMQ 消息组消费者选择?
Posted
技术标签:
【中文标题】跨多个队列的 ActiveMQ 消息组消费者选择?【英文标题】:ActiveMQ Message Group Consumer Selection Across Multiple Queues? 【发布时间】:2014-01-22 05:54:41 【问题描述】:ActiveMQ Message Groups 是一个很棒的功能,用于在多个消费者之间进行负载平衡。简而言之:根据嵌入在消息中的组标识符 (JMSXGroupID
),将消息流划分为单个队列的多个消费者。 (因此,消费者 1 将获得所有带有 JMSXGroupID = a
的消息,消费者 2 将获得所有带有 JMSXGroupID = b
的消息,依此类推。)
现在,假设您有 2 个队列:A
和 B
,并假设在流经两个队列的消息中使用了一致的 JMSXGroupID
s 分类法。代理为队列A
上的JMSXGroupID = ABC
选择的消费者会是代理为队列B
上的JMSXGroupID = ABC
选择的同一连接中的消费者吗?
我怀疑这个问题的答案是“否”。有太多变量在起作用:如果代理为A
选择的消费者没有B
的对应消费者会发生什么?如果代理为A
选择的消费者有多个 对应B
的消费者,会发生什么?在这些情况下,没有明显的正确答案。
但是,我们可以模拟这种行为吗?例如,composite destination 上的消费者可能是一个可行的解决方案 - 确保 A
和 B
上的所有消费者都在复合目标 A,B
上消费,并且您可能正在开展业务 - 但 ActiveMQ 不会出现支持从复合目的地消费。
我发现的唯一解决方案是简单地将A
和B
的消息推送到一个队列上——称之为AB
——并在其上拥有一个独占消费者。您现在必须区分“A
messages”和“B
messages”,但您可以使用标题轻松做到这一点。
但是,这个解决方案闻起来很有趣。 (您现在必须假设生产者会尽职尽责地将特殊标头应用于他们的消息,或修改您的有效负载。)是否有解决方案可以确保跨两个单独队列 @987654345@ 和 B
的消费者始终位于同一连接上?
【问题讨论】:
【参考方案1】:正如您正确计算的那样,消息组仅适用于单个队列。多个队列之间没有协调。
通常,当您使用消息组时,您会尝试保证消息的排序不仅包括传递,还包括处理——也就是说,特定实体的所有事件都按顺序处理。魔鬼总是在你的用例的细节中,但是将所有相关的消息放到一个队列中会给你你想要的结果。为了以不同的方式处理它们,您需要将某种多路复用逻辑放入您的消费者中,以根据消息有效负载做出决定 - 正如您所说的那样,众所周知的标头是解决方案的良好候选者。
要绕过确保客户端显式设置的先决条件,您可以做的是编写一段 Camel 路由逻辑,代表您执行此操作 - 这只有在 ActiveMQ 5.9 中添加的 broker: component 才有可能.这个想法是生产者看到两个单独的队列 - 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
标头。
【讨论】:
以上是关于跨多个队列的 ActiveMQ 消息组消费者选择?的主要内容,如果未能解决你的问题,请参考以下文章