Мы недавно мигрировали из 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();
}
}
}
Метод вставки - это простометод, который сохраняет сущность и требует транзакции.