запрос размера очереди Artemis не выполняется - PullRequest
0 голосов
/ 18 июня 2020

В приложении с весенней загрузкой, использующем artemis, мы стараемся избегать очередей, содержащих слишком много сообщений. Намерение состоит в том, чтобы помещать новые сообщения только в том случае, если количество сообщений, находящихся в настоящее время в очереди, падает ниже определенного предела, например 100 сообщений. Однако это, похоже, не работает, но мы не знаем, почему и какой «правильный» метод будет для реализации этой функции. Количество сообщений, извлеченных приведенным ниже кодом, всегда равно 0, хотя в gui есть сообщения.

Чтобы воспроизвести проблему, я установил 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 какие-либо другие возможности доступа к очереди?

Обновление : я прочитал другой пост и документацию , но я не знаю о том, как получить ClientSession.

1 Ответ

0 голосов
/ 18 июня 2020

Есть некоторые предостережения относительно использования QueueBrowser для подсчета количества сообщений в очереди. Первый отмечен в QueueBrowser JavaDo c:

Сообщения могут приходить и истекать во время сканирования. JMS API не требует, чтобы содержимое перечисления было статическим c снимком содержимого очереди. Видны ли эти изменения или нет, зависит от поставщика JMS.

Таким образом, уже подсчет может быть неточным на 100%.

Тогда есть факт, что сообщения могут все еще быть технически в очереди, которые были отправлены потребителю, но еще не подтверждены. Эти сообщения не будут учитываться QueueBrowser, даже если они могут быть отменены обратно в очередь в любой момент, если связанный потребитель закрывает свое соединение.

Проще говоря, JMS API не обеспечивает действительно надежного способ определения количества сообщений в очереди. Кроме того, Spring JMS привязан к JMS API. У него нет другого способа взаимодействия с брокером JMS. Учитывая это, вам необходимо использовать механизм c, определяемый поставщиком, для определения количества сообщений.

ActiveMQ Artemis имеет богатый API управления, который доступен, среди прочего, через специально созданные сообщения JMS. Вы можете увидеть это в действии в примере «Управление» , который поставляется с ActiveMQ Artemis в каталоге examples/features/standard/management. Он демонстрирует, как использовать ресурсы JMS и вспомогательные классы c, определяемые поставщиком, для получения количества сообщений для очереди JMS. По сути, это то же самое решение, что и в другом сообщении, которое вы упомянули , но оно использует JMS API, а не «основной» API ActiveMQ Artemis.

...