首页 > 解决方案 > JMS Consumer 阻塞其他 JMSXGroups

问题描述

我试图弄清楚当消息回滚到队列时是否会影响消费者的消息处理顺序。我在下面有一些简单的代码可以帮助我重现问题。我只是按特定顺序将消息推送到具有不同 JMSXGroupIds 的队列中:

  1. “A1”(JMSXGroupId:1)
  2. “B1”(JMSXGroupId:2)
  3. “A2”(JMSXGroupId:1)
  4. “C1”(JMSXGroupId:3)
  5. “B2”(JMSXGroupId:2)

该代码使 A1 回滚(它最初重试消息 3 次)并延迟返回队列。然而,消费者然后等待直到它可以再次拿起 A1(在等待延迟的时间之后),这意味着 B1 和 C1 组被阻塞在 A1 后面并且永远不会被处理。

理想情况下,我希望的是,当 A1 被放回队列并被告知等待时,消费者会拿起 B1 和 C1 ......我最终想要做的是阻止一个 JMSXGroup 阻止其他消费者. 此外,可能值得补充的是,我需要保持 A (A1,A2,A3...) 的消息序列顺序,并希望通过将它们留在队列中来做到这一点,而不是必须为异常构建一些管理解决方案。

onException(Exception.class)
            .log("Exception Caught !! ")
            .redeliveryDelay("1000")
            .maximumRedeliveries(3)
            .handled(false)
            .markRollbackOnly()
            .log("log:output");

    from("amq:queue:mailbox?concurrentConsumers=1")
            .to(logEndpoint)
            .process(exchange -> {
                if(exchange.getIn().getBody(String.class).contains("A")) {
                    throw new Exception("Found A");
                }
            });

我正在使用带有事务处理路由的基于 Java 的 Apache Camel 微服务。没什么特别的,但如果需要,我可以提供更多细节/配置细节。

提前致谢

标签: javaspring-bootapache-cameljms

解决方案


队列上的严格排序必然会遇到这样的问题,因为队列必须遵守其基本的先进先出(即 FIFO)语义。即使 B1 在 A1 失败后立即被拾取,您也必须等待消费 A2 直到 A1 被消费以保持顺序,并且由于队列必须被消费 FIFO 这将阻止 C1 和任何其他消息的消费在它后面。


推荐阅读