Как настроить политику доставки ActiveMQ Artemis, чтобы не блокировать очередь - PullRequest
0 голосов
/ 04 июля 2019

Фон

У меня есть очередь сообщений JMS на Apache Artemis 2.7.0.redhat-00056. Брокер настроен на redelivery-delay из 10 минут. Если я опубликую сообщение в очереди, и оно не будет получено потребителем, то оно возвращается в очередь как запланированное сообщение, которое должно быть доставлено через 10 минут. Любые последующие сообщения, которые публикуются, обрабатываются сразу, поэтому очередь не блокируется запланированным сообщением.

Если несколько сообщений отправляются в быстрой последовательности, то происходит то, что все они терпят неудачу и планируются на 10 минут. В этом случае похоже, что Артемида пытается сохранить порядок сообщений.

Документация

Документы о повторной доставке говорят следующее:

Другие последующие сообщения будут доставляться регулярно, только задержанное сообщение будет отправлено обратно в очередь после задержки.

Документация по доставке

Проблема

Мне кажется непоследовательным, что если вы публикуете сообщения в тесной последовательности, кажется, что Артемида сохраняет порядок, тогда как если между сообщениями есть небольшая задержка, очередь не блокируется, и только неудачные сообщения планируются с задержкой (согласно документации).

Я пытаюсь найти решение, чтобы в случае сбоя одного сообщения и его повторной доставки в течение 10 минут оно не блокировало последующие сообщения.

Пример

Для этого не нужно ничего особенного. Как описано, вам просто нужно отправить несколько сообщений в быстрой последовательности в очередь с политикой повторной доставки в брокере. Я тестировал на следующем примере:

Приложение Spring, которое при запуске выдает пять сообщений.

@SpringBootApplication
public class ArtemisTestApplication
{

    private Logger logger = LoggerFactory.getLogger(ArtemisTestApplication.class);

    @Autowired
    private JmsTemplate jmsTemplate;

    @PostConstruct
    public void init()
    {
        send("Message1");
        send("Message2");
        send("Message3");
        send("Message4");
        send("Message5");
    }

    public void send(String msg)
    {
        logger.debug("Sending message :{}", msg);
        jmsTemplate.convertAndSend("jms.queue.TestQueue", msg);
    }

    public static void main(String[] args)
    {
        SpringApplication.run(ArtemisTestApplication.class, args);
    }

}

Использовать сообщения и выдавать ошибку, чтобы активировать политику доставки.

@Component
public class TestConsumer
{
    private Logger logger = LoggerFactory.getLogger(TestConsumer.class);

    @JmsListener(destination = "jms.queue.TestQueue")
    public void receive(TextMessage message) throws JMSException
    {
        logger.debug("Message received: {}", message.getText());
        throw new RuntimeException("Force redelivery policy");
    }
}

Приложение было создано с использованием spring boot initializr . Помимо присвоения ему имени, единственное, что было отмечено, это зависимость от Артемиды при обмене сообщениями.

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-artemis</artifactId>
    </dependency>

В application.properties я настроил свойства подключения к локально работающему экземпляру Artemis.

spring.artemis.mode=native
spring.artemis.host=localhost
spring.artemis.port=61616
spring.artemis.user=
spring.artemis.password=

И на брокере я настроил очередь с политикой повторной доставки. Примечание: здесь я установил задержку на 0, и проблема по-прежнему возникает в том, что все сообщения блокируются до тех пор, пока первое сообщение не выполнит три попытки и не будет перемещено в DLQ. Если вы измените задержку на положительное число, то увидите, что все пять сообщений запланированы для доставки позже.

<address-settings>      
    <address-setting match="jms.queue.TestQueue">            
        <dead-letter-address>DLQ</dead-letter-address>                      
        <redelivery-delay>0</redelivery-delay>    
        <max-delivery-attempts>3</max-delivery-attempts>
    </address-setting>    
  </address-settings>

<addresses>     
    <address name="DLQ">            
        <anycast>               
          <queue name="DLQ" />            
        </anycast>         
      </address>       
      <address name="jms.queue.TestQueue">            
        <anycast>               
          <queue name="jms.queue.TestQueue" />            
        </anycast>         
      </address>                      
</addresses>

1 Ответ

0 голосов
/ 09 июля 2019

Я пришел к выводу, что это ошибка с Артемидой.Я поднял билет на это, и комментарий был оставлен кому-то еще, испытывающему ту же проблему.

https://issues.apache.org/jira/browse/ARTEMIS-2417

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

...