Задержка повторной доставки сообщения JMS - PullRequest
9 голосов
/ 09 августа 2010

У меня есть JMS-клиент, который может получать ssh к удаленным системам после получения сообщения (и делать там разные вещи - не относящиеся к вопросу).Возможно, что за короткое время поступят сотни таких сообщений, которые необходимо обработать как можно скорее.

Однако возможно также, что некоторые удаленные системы будут недоступны при получении сообщения, поэтому ониследует отложить на потом (например, 1 час или около того).Лучшим решением было бы поместить сообщение обратно в очередь с некоторым набором значений задержки, что сообщит JMS-брокеру не пытаться доставить сообщение снова в течение часа.

Что не в порядке:спать в получающей ветке и просыпаюсь через час.Поскольку пул потребителя сообщений ограничен (например, доступно 8 подключений), поскольку 8 недоступных систем блокируют всю обработку без необходимости, что недопустимо.

Я не нашел настройки ни для сообщения, ни длясама очередь для такого значения "задержки", она существует?

Обходное решение - использовать вторую очередь для хранения сообщений в недоступных системах и обрабатывать их отдельно.Но это не очень элегантное решение и требует дополнительного программирования.Возможно, есть лучший способ.

Ответы [ 6 ]

9 голосов
/ 25 апреля 2014

Спецификация JMS 2.0 определяет «задержку доставки», когда клиент может указать значение задержки доставки в миллисекундах для каждого отправляемого сообщения. Это значение определяет время доставки сообщения, которое является суммой задержки доставки сообщения и GMT, когда оно было отправлено (для транзакционных отправок это время, когда клиент отправляет сообщение, а не время совершения транзакции).

Время доставки сообщения - это самое раннее время, когда провайдер JMS может сделать сообщение видимым в целевом месте назначения и доступным для доставки потребителям. Поставщик не должен доставлять сообщения до истечения времени доставки.

Эта функция очень удобна для сценария, описанного выше.

4 голосов
/ 22 мая 2013

В этих ситуациях используются управляемые контейнером транзакции.Транзакция запускается, когда контейнер вызывает метод onMessage, и фиксируется, если метод onMessage завершается успешно (сбой при возникновении исключения RuntimeException или при вызове setRollBackOnly из контекста MessageDrivenBean).Вы также можете настроить интервал повторной доставки и максимальное количество повторных доставок.

Если вы используете OpenMQ с сервером Glassfish, вы можете настроить его внутри дескриптора ejb-jar.xml.Внутри дескриптора ejb-jar.xml задайте свойства endpointExceptionRedeliveryInterval (в миллисекундах) и endpointExceptionRedeliveryAttempts (количество раз, когда сообщение доставляется до его отправки в очередь мертвых сообщений).Вот пример:

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar  xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd"
    version="3.1">    
    <enterprise-beans>
        <message-driven>
            <ejb-name>EjbName</ejb-name>
            <ejb-class>com.example.MyMessageDrivenBean</ejb-class>
            <messaging-type>javax.jms.MessageListener</messaging-type>
            <transaction-type>Container</transaction-type>
            <activation-config>
                <activation-config-property>
                    <activation-config-property-name>destination</activation-config-property-name>
                    <activation-config-property-value>someQueue</activation-config-property-value>
                </activation-config-property>
                <activation-config-property>
                   <activation-config-property-name>destinationType</activation-config-property-name>
                   <activation-config-property-value>javax.jms.Queue</activation-config-property-value>
                </activation-config-property>

                <activation-config-property>
                    <activation-config-property-name>endpointExceptionRedeliveryInterval</activation-config-property-name>
                    <activation-config-property-value>5000</activation-config-property-value>
                </activation-config-property>
                <activation-config-property>
                    <activation-config-property-name>endpointExceptionRedeliveryAttempts</activation-config-property-name>
                    <activation-config-property-value>4</activation-config-property-value>
                </activation-config-property>
            </activation-config>
        </message-driven>
    </enterprise-beans>
</ejb-jar>

И внутри объекта, управляемого сообщениями, выдается исключение RuntimeException, чтобы пометить его как сбойное, и сообщение будет возвращено в очередь.

Вот также свойства конфигурациидля сервера WebLogic: http://docs.oracle.com/cd/E12839_01/apirefs.1111/e13952/pagehelp/JMSjmstemplatesjmstemplateconfigredeliverytitle.html

3 голосов
/ 09 августа 2010

Это невозможно через JMS API до JMS 2.0.Как правило, транспорты сообщений оптимизированы для максимально быстрой доставки сообщений и не имеют планировщиков для хранения сообщений для повторной доставки через некоторый произвольный интервал.Предполагая, что есть транспортный провайдер, обладающий такой функциональностью, все, что вы пишете, будет привязано к этому транспортному провайдеру, потому что, хотя код может быть JMS-совместимым, само приложение будет полагаться на это поведение, специфичное для поставщика.1002 * См. Ответ @ Shashi для ответа, который относится к версиям MQ, поддерживающим JMS 2.0.

0 голосов
/ 04 апреля 2018

Добрый день!

Точно для Oracle WebLogic Server есть два параметра:

0 голосов
/ 22 августа 2017

На glassfish следующие ссылки могут использоваться.

https://docs.oracle.com/cd/E19798-01/821-1794/aeooq/index.html

На приведенной выше ссылке вы получите список свойств активации, которые поддерживаются glassfish.Например, endpointExceptionRedeliveryAttempts -
Количество повторных доставок сообщения, когда MDB генерирует исключение во время доставки сообщения

Затем у вас есть следующая ссылка, которая описывает допустимые элементы xml для использования в sun-ejb-jar.xml,который поддерживается Glassfish.https://docs.oracle.com/cd/E19798-01/821-1750/beaqm/index.html

Наконец, вы можете настроить Mdb, как показано в следующем фрагменте.

<ejb>
    <ejb-name>MyMdbWith0MsRedeliveryDelayAndMultipleRedeliveriesMdb</ejb-name>
    <bean-pool>
        <steady-pool-size>1</steady-pool-size>
        <resize-quantity>1</resize-quantity>
        <max-pool-size>1</max-pool-size>
    </bean-pool>
    <mdb-resource-adapter>
        <activation-config>
            <activation-config-property>
                <activation-config-property-name>endpointExceptionRedeliveryAttempts</activation-config-property-name>
                <activation-config-property-value>1000</activation-config-property-value>
            </activation-config-property>
            <activation-config-property>
                <activation-config-property-name>endpointExceptionRedeliveryAttempts</activation-config-property-name>
                <activation-config-property-value>0</activation-config-property-value>
            </activation-config-property>
        </activation-config>              
    </mdb-resource-adapter>
</ejb>

Это должно гарантировать, что для этого конкретного mdb glassfish немедленно доставит сообщение, и еслив противном случае он сразу же попытается.

В вашем проекте WAR создайте файл sub-ejb-jar.xml и поместите его в WEB-INF / sun-ejb-jar.xml.

Есливы используете maven, это будет ваш путь src / main / webapp / WEB-INF / sub-ejb-jar.xml в компоненте проекта войны.

0 голосов
/ 25 апреля 2014

Я бы посмотрел на проблему как: Доступен пул потребителей сообщений jms ... пока некоторые внутренние ресурсы (например, ssh) недоступны для завершения сообщения.

Если вы согласны с этим, возникает проблема: почему доступен пул потребителей, поскольку он не может завершить потребление? Если бы у вас не было пула, то сообщения могли бы накапливаться в очереди ... до тех пор, пока они не стали доступны ... и было бы неплохо продолжить, когда они будут доступны. Тогда, если это так, вам просто нужен компонент мониторинга для запуска / остановки пула в зависимости от наличия ресурсов. Вам не нужно ждать 1 час, но пока бэкэнд не доступен. в конце концов, jms - это все, но не инструмент мониторинга.

...