ActiveMQ потерял сообщения, если на MDB нет ожидающих фиксации с XA и RA - PullRequest
0 голосов
/ 13 декабря 2018

Мы недавно мигрировали из Artemis в ActiveMQ, и теперь мы сталкиваемся с некоторым странным поведением с нашими компонентами, управляемыми сообщениями.

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

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

Мы используем XA и Resource Adapter с приложением WildFly Swarm.Похоже, что как только транзакция начинается с MDB и происходит ожидание фиксации, приложение уведомляет брокера о необходимости удержать сообщение, даже если потребитель умирает.Если транзакция отсутствует, как только брокер обнаруживает, что потребитель потерял соединение, сообщения удаляются из очереди.

Некоторые сведения:

  • Даже при определении требуемой транзакции и управления контейнером происходит то же самое
  • При использовании auto или dups ack происходит то же самое
  • Сообщения являются постоянными

Нам не хватает некоторыхконфигурация с ActiveMQ?Мы не находим никакого другого свойства, говорящего о таком поведении с MDB и транзакциями.Что говорит брокеру, что он должен хранить сообщения с идущими транзакциями?Есть способ сохранить все сообщения в случае сбоя, используя MDB и XA?

Вот простой код MDB со сценарием тестирования:

@MessageDriven(activationConfig = {
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
    @ActivationConfigProperty(propertyName = "destination", propertyValue = "task-processor"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
    @ActivationConfigProperty(propertyName = "maxSessions", propertyValue = "20")
})
@ResourceAdapter("activemq-rar.rar")
public class MyMDB implements MessageListener {

@Inject
private CartaoService service;

@Override
public void onMessage(Message message) {

    try {
        // 0 - No transaction
        // 1 - Will be a transaction with a pending commit
        int t = new Random().nextInt(2);

       // Just a entity to persist and have a pending commit
        Cartao c = new Cartao();
        c.setIdBoard(1l);
        c.setNome(((TextMessage) message).getText());
        c.setStatus("ON");
        c.setTempo(10l);

        // Prints the message id and if there is a transaction
        System.out.println(((TextMessage) message).getJMSMessageID() + " - " + t);

        // Sometimes we will have a commit pending
        if (t == 1)
           service.insert(c);
        TimeUnit.SECONDS.sleep(30);
        System.out.println("END");
    } catch (Exception e) {
        e.printStackTrace();
    }

}


}

Метод вставки - это простометод, который сохраняет сущность и требует транзакции.

...