我们有一个MQ Queue,它从我们控制的外部系统接收消息。 我们处理传入消息的系统是一个至关重要的系统,无论如何都需要以27x7的速度启动和运行。
处理传入消息的顺序也是不可协商的,这意味着我们需要按照它们到达的顺序处理它们。
为了确保我们的系统100%可用,我们将系统部署到一堆能够处理这些消息的物理机器上。
一旦消息到达我们的系统,我们就建立了一种机制,以确保消息处理不会出现故障,同时由于并行处理而获得一些性能提升。对我们而言,性能提升是一件好事,但它是一个副作用,因为我们的主要目标是确保正确的处理顺序,同时确保高可用性。
我的想法是在每台机器上都有一个MDB能够处理传入的消息,但一次只有一个活跃的消费者。
我们使用Webshere MQ作为JMS提供程序,使用Webshere Application Server 8.5来部署我们的应用程序。
多个消费者收听相同队列的问题似乎不是一个可行的解决方案,因为当消息大量到达时,他们将循环传递给所有消费者,并且无法控制这将如何发生并且消息很容易失序。
当我手动停止所有侦听器但显然消息按顺序处理时。但是手动关闭和启动这样的监听器肯定不是HA解决方案。
我们可以实施监控流程来检查系统的运行状况并关闭或根据需要启动它们,但这对我来说仍然看起来太弱了。 实际上我们想要的是让所有的监听器都启动并运行,但只有一个接收消息。如果那个因为某种原因而失败,那么坐在那里的另一个将变为活动并开始处理消息。
最初我们考虑使用主题而不是队列,但这会带来其他问题,如下所示:
无论如何,在我看来,它必须是一个现有的模式来适应这种情况。任何帮助,建议将不胜感激。
解决方案不一定是特定的MQ,任何想法都是受欢迎的。
提前致谢
答案 0 :(得分:5)
创建第二个队列,我们将其称为“控制队列”。进入这个队列,放一条消息,我们称之为“令牌”。更改申请处理如下:
COMMIT
消息。 COMMIT
完成输入队列上的事务,并使令牌可供其他MDB使用。除了在同步点下具有令牌的MDB之外,不会对输入队列进行处理。但是,您可以在令牌上等待任意数量的MDB。任何一个失败都会让其他人立即接管。
顺便说一下,不需要使用XA。 WMQ的单阶段COMMIT非常适用于此。
答案 1 :(得分:1)
当应用程序尝试通过其MDB侦听器使用队列时,我们可以通过使用DEFSOPT(Exclusive)定义队列来限制它们。这将确保只有一个应用程序可以使用该队列中的消息。
如果我们希望仅限制应用程序的一个实例,请将其定义为NOSHARE。这样,一个应用程序的一个实例可以一次获取队列中的消息。当前的一个人释放锁定时,其他人将轮到他们。
答案 2 :(得分:0)
在我看来,同步多个消费者并不是一个大问题,而且是最有效的解决方案。我不知道在哪里必须记录处理结果(可能再次JMS队列?),但我会尝试在此之前使用lightweitght代理。您可以使用时间戳或通过JMS实现计数器以保留顺序。 消费者可以并行执行,然后在支持队列中发布。比单个代理可以使用queuebrowser然后是事务来命令它们。这个经纪人应该“痴迷”。
的Alessandro