MQ队列有多个消费者,但只有一个处于活动状态

5
我们有一个MQ队列,接收来自我们无法控制的外部系统的消息。我们处理传入消息的系统是关键的,需要24/7运行,不论发生什么。
处理传入消息的顺序也是不可协商的,这意味着我们需要按照它们到达时的确切顺序进行处理。
为了确保我们的系统100%可用,我们将我们的系统部署在一堆能够处理这些消息的物理机器上。
一旦消息到达我们的系统,我们就会实施一种机制,以确保消息处理不会失序,同时获得一些性能提升作为结果。对于我们来说,性能提升是好的,但它实际上是一个副作用,因为我们的主要目标是高可用性,同时保证正确的处理顺序。
我的想法是,在每台单独的机器上配置能够处理传入消息的MDB,但一次只有一个活动消费者。
我们使用Webshere MQ作为JMS提供程序,并使用Webshere Application Server 8.5部署应用程序。
多个消费者同时监听同一队列的问题似乎不是可行的解决方案,因为当消息批量到达时,它们会循环通过所有消费者,并且没有办法控制这将如何发生,消息很容易失去顺序。
当我手动停止除一个监听器以外的所有监听器时,显然消息按顺序处理。但手动关闭和启动这些监听器肯定不是高可用性的解决方案。
我们可以实施监控过程来检查系统的健康状况,并根据需要关闭或启动它们,但这仍然对我来说似乎太弱。
实际上,我们想要的是所有监听器都在运行,但只有一个接收消息。如果其中一个出现问题,那么另一个正在那里的监听器将变为活动状态并开始处理消息。
最初,我们考虑使用主题而不是队列,但这会带来其他问题,如下所示:
1.我们无法控制我们消息的来源 2.我们拥有的大量消息会使我们遇到麻烦,因为必须是持久的,当他们回来时必须处理大量的未决消息。 3.输入队列已经是集群的一部分,更改所有基础结构需要进行大量工作
总之,在我看来,必须存在一种现有的模式来适应这种情况。任何帮助、建议将不胜感激。
解决方案不必是特定的MQ解决方案,欢迎任何想法。
提前感谢。
3个回答

6
创建第二个队列,我们称之为"控制队列"。将一个单一的消息放入该队列中,我们称之为"令牌"。更改应用程序处理方式如下:
  1. 在控制队列上监听消息。
  2. 在同步点下从控制队列获取令牌。
  3. 在同步点下将相同的令牌消息放回控制队列。
  4. 在同步点下处理来自正常输入队列的事务。
  5. 提交消息。
  6. 循环执行。
提交完成了输入队列上的事务,并使得其他MDB可以使用令牌。除拥有同步点下令牌的MDB外,不会发生任何输入队列的处理。 但是,您可以让任意数量的MDB等待令牌。 其中任何一个MDB失败都可以立即由其他MDB接管。
顺便说一句,无需使用XA。 WMQ的单阶段COMMIT非常适用于此。

非常感谢Rob。这看起来是一个非常好的想法,而且也相当有趣。我需要创建一个POC Spike,一旦我让它能够工作,我会回来分享我的发现。 - Julian
谢谢Rob。一切都按照预期正常工作。我注意到处理整个测试批次的时间与仅有一个MDB消费者时相比翻倍,与我的四个消费者全部并行运行时相比慢了约8倍(但是获取消息的顺序不正确)。 无论如何都可以工作,我认为有改进处理时间的方法。仍然遗憾的是,在将消息写入队列时无法附加序列号。这将非常好地解决了我的问题。 无论如何,感谢您提出的好建议和支持。 - Julian

2

当应用程序通过它们的MDB监听器尝试使用队列时,我们可以通过使用DEFSOPT(Exclusive)定义队列来限制它们。这将确保只有一个应用程序可以消耗该队列中的消息。

如果我们希望仅限于应用程序的一个实例,则将其定义为NOSHARE。这样,一个应用程序的一个实例一次只能获取队列上的消息。其他人会在当前实例释放锁定时获得他们的机会。


感谢您的建议。我希望能够在同一个工作空间中验证它的工作原理。不幸的是,对于我来说很难在我的笔记本电脑上安装 WAS 实例和 MQ 管理器并测试您的解决方案。 - Julian

0
在我看来,同步多个消费者不是一个大问题,也是最有效的解决方案。我不知道处理结果应该记录在哪里(也许再次使用JMS队列?),但在此之前,我会尝试使用轻量级代理。您可以使用时间戳或在JMS上实现计数器以保持顺序。 消费者可以并行执行,然后发布到支持队列中。然后单个代理可以使用队列浏览器对它们进行排序,然后进行事务处理。这个代理应该被“看门狗”监视。
亲 爱 的 Alessandro

谢谢Alessandro。您能否更具体地说明一下“轻量级代理”是什么意思?这是一个小型消费者,将附加计数器或分析时间戳吗? - Julian
只是简单地提一下,我尝试使用JMSTimestamp来重新排列消息,但没有成功。分析一个月的工作数据发现,有很多情况下我们会在同一毫秒内收到多条消息,最多的时候达到了每毫秒22条消息。 - Julian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接