【问题标题】:querying artemis queue size fails查询 artemis 队列大小失败
【发布时间】:2020-06-19 00:45:35
【问题描述】:

在使用 artemis 的 Spring Boot 应用程序中,我们尽量避免包含太多消息的队列。目的是仅在当前队列中的消息数量低于某个限制时才放入新消息,例如100 条消息。但是,这似乎不起作用,但我们不知道实现该功能的原因或“正确”方法是什么。尽管在 gui 中有消息,但下面代码提取的消息数始终为 0。

为了重现问题,我在本地安装了 apache-artemis-2.13.0。

我们正在做类似以下的事情

if (!jmsUtil.queueHasNotMoreElementsThan(QUEUE_ALMOST_EMPTY_MAX_AMOUNT, reprocessingMessagingProvider.getJmsTemplate())) {
    log.info("Queue has too many messages. Will not send more...");
    return;
}

jmsUtil 的实现方式类似于

public boolean queueHasNotMoreElementsThan(int max, JmsOperations jmsTemplate) {
    return Boolean.TRUE.equals(
            jmsTemplate.browse((session, queueBrowser) -> {
                Enumeration enumeration = queueBrowser.getEnumeration();
                return notMoreElemsThan(enumeration, max);
            }));
}

private Boolean notMoreElemsThan(Enumeration enumeration, int max) {
    for (int i = 0; i <= max; i++) {
        if (!enumeration.hasMoreElements()) {
            return true;
        }
        enumeration.nextElement();
    }
    return false;
}

作为检查,我还使用以下方法直接给我队列中的消息数。

public int countPendingMessages(String destination, JmsOperations jmsTemplate) {
    Integer totalPendingMessages = jmsTemplate.browse(destination,
            (session, browser) -> Collections.list(browser.getEnumeration()).size());
    int messageCount = totalPendingMessages == null ? 0 : totalPendingMessages;
    log.info("Queue {} message count: {}", destination, messageCount);

    return messageCount;
}

提取队列大小的方法似乎也被其他人使用,并且基于QueueBrowser的文档:The getEnumeration method returns a java.util.Enumeration that is used to scan the queue's messages.

以上是如何获取队列大小的正确方法吗?如果是这样,问题的原因可能是什么?如果不是,应该如何查询队列大小? spring 是否提供任何其他访问队列的可能性?

更新:我阅读了another postdocumentation,但我不知道如何获取ClientSession。

【问题讨论】:

    标签: spring-boot activemq-artemis


    【解决方案1】:

    使用QueueBrowser 计算队列中的消息数有一些注意事项。第一个在QueueBrowser JavaDoc中注明:

    扫描完成时,邮件可能会到达并过期。 JMS API 不要求枚举的内容是队列内容的静态快照。这些更改是否可见取决于 JMS 提供者。

    所以计数可能不是 100% 准确。

    还有一个事实是,从技术上讲,队列中可能仍有消息已被分派给消费者但尚未被确认。这些消息不会被QueueBrowser 计算在内,即使如果相关消费者关闭其连接,它们可能随时被取消返回队列。

    简单地说,JMS API 没有提供真正可靠的方法来确定队列中的消息数量。此外,“Spring JMS”与 JMS API 相关联。它没有任何其他方式与 JMS 代理进行交互。鉴于此,您需要使用特定于提供程序的机制来确定消息计数。

    ActiveMQ Artemis 具有丰富的管理 API,除其他外,还可以访问特殊构造的 JMS 消息。您可以在 examples/features/standard/management 目录中的 ActiveMQ Artemis 附带的 "Management" example 中看到这一点。它演示了如何使用 JMS 资源和特定于提供程序的帮助程序类来获取 JMS 队列的消息计数。这与the other post you mentioned 中给出的解决方案基本相同,但它使用 JMS API 而不是 ActiveMQ Artemis“核心”API。

    【讨论】:

    • 对于我们的应用程序来说,这将是相当困难的,因为需要一些对象,我不知道如何在 Spring 中获取它们。在org.springframework.jms.core.JmsTemplate 中,getSession 方法是例如受保护。并且 QueueSession 不可用。
    • Spring中不能使用JMS API?
    猜你喜欢
    • 2018-06-30
    • 2016-07-19
    • 2018-08-19
    • 2019-04-29
    • 2012-03-01
    • 2019-08-16
    • 2021-10-02
    • 2012-10-21
    • 2020-08-03
    相关资源
    最近更新 更多