5

我们有一个 MQ 队列,它从我们无法控制的外部系统接收消息。我们处理传入消息的系统是一个关键系统,无论如何都需要启动并运行 27x7。

处理传入消息的顺序也是不可协商的,这意味着我们需要完全按照它们到达的顺序来处理它们。

为了确保我们的系统 100% 可用,我们将系统部署到了一堆能够处理这些消息的物理机器上。

一旦消息到达我们的系统,我们就会建立一种机制来确保消息处理不会出现故障,同时还可以通过并行处理获得一些性能提升。对我们来说,性能提升是一件好事,但它是一个副作用,因为我们的主要目标是高可用性,同时确保正确的处理顺序。

我的想法是在每台机器上都有一个 MDB 能够处理传入的消息,但一次只有一个活跃的消费者。

我们使用 Webshere MQ 作为 JMS 提供者和 Webshere Application Server 8.5 来部署我们的应用程序。

多个消费者监听同一个队列的问题似乎不是一个可行的解决方案,因为当消息批量到达时,它们将被循环传递给所有消费者,并且无法控制这将如何发生以及消息很容易失序。

当我手动停止所有侦听器时,显然消息已按顺序处理。但是手动关闭和启动此类监听器绝对不是 HA 解决方案。

我们可以建立监控流程来检查系统的健康状况并根据需要关闭或启动它们,但这对我来说仍然太弱了。事实上,我们想要的是让所有侦听器都启动并运行,但只有一个侦听器接收消息。如果那个人因为某种原因宕机了,那么另一个坐在那里的人将变得活跃并开始处理消息。

最初我们考虑使用主题而不是队列,但这会带来其他问题,如下所示:

  1. 我们无法控制信息的来源
  2. 我们拥有的大量消息会给我们带来麻烦,因为我们的订阅者必须是持久的,当回来时必须处理大量未决消息
  3. 输入队列已经是集群的一部分,更改所有基础设施需要大量工作

无论如何,在我看来,它必须是一种现有的模式来适应这种情况。任何帮助,建议将不胜感激。

解决方案不必是特定的 MQ 解决方案,欢迎提出任何想法。

提前致谢

4

3 回答 3

6

创建第二个队列,我们​​将其称为“控制队列”。在这个队列中,放入一条消息,我们称之为“令牌”。变更申请处理如下:

  1. 在控制队列上侦听消息。
  2. 从同步点下的控制队列中获取令牌。
  3. 将相同的令牌消息放回控制队列,也在同步点下。
  4. 处理来自正常输入队列的事务,也在同步点下。
  5. COMMIT消息。
  6. 环形。

完成输入队列上的COMMIT事务并使令牌对其他 MDB 可用。除了在同步点下具有令牌的 MDB 之外,不会对输入队列进行任何处理。但是,您可以让任意数量的 MDB 等待令牌。他们中的任何一个失败都会让其他人立即接管。

顺便说一句,不需要使用 XA。WMQ 的单相 COMMIT 非常适用于此。

于 2013-09-19T18:42:58.983 回答
2

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

如果我们希望仅限于应用程序的一个实例,请将其定义为 NOSHARE。因此,一个应用程序的一个实例可以一次获取队列中的消息。当当前释放锁时,将轮到其他人。

于 2016-11-15T13:35:18.940 回答
0

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

亚历山德罗

于 2013-09-19T09:54:38.737 回答