У меня есть потребительское приложение, которое использует Spring Boot JMS для прослушивания сообщения из очереди. Это приложение подключено к кластеру ActiveMQ с аварийным переключением для обеспечения высокой доступности. Но у меня возникает следующая проблема: когда я выключаю один из брокеров, и приложение обрабатывает одно сообщение, это сообщение не удаляется из очереди, а когда приложение подключается к другому брокеру, сообщение доставляется повторно. Проблема в том, что сообщение было обработано в первый раз, и мне не нужно его обрабатывать повторно.
Я искал режимы подтверждения и пытался использовать клиентский режим для принудительного подтверждения перед обработкой сообщения. Но я не работал. Любая идея??
Я объявил следующие бобы:
@Bean
public ActiveMQConnectionFactory jmsConnectionFactory() {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerUrl);
connectionFactory.setUserName(brokerName);
connectionFactory.setPassword(brokerPassword);
connectionFactory.setTrustAllPackages(true);
return connectionFactory;
}
@Bean
public JmsTemplate jmsTemplate() {
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(jmsConnectionFactory());
jmsTemplate.setSessionTransacted(false);
jmsTemplate.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
jmsTemplate.setDefaultDestinationName(REMOTE_T);
return jmsTemplate;
}
@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerFactory(
@Qualifier("jmsConnectionFactory") ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setSessionTransacted(false);
factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
configurer.configure(factory, connectionFactory);
return factory;
}
Код моего слушателя:
@JmsListener(destination = "Consumer.consumer1.VirtualTopic.TopicPrueba", containerFactory = "jmsListenerContainerFactory")
public void receiveMessageFromContacts(Message message) {
try {
message.acknowledge();
TextMessage txtMessage = (TextMessage)message;
mensajesConsumer1++;
System.out.println("First Consumer:"+ txtMessage.getText()+ " received:"+mensajesConsumer1);
}catch(JMSException e) {
e.printStackTrace();
}
}
Не уверен, правильно ли я понял режим подтверждения клиента.
Пожалуйста помоги! :)
Заранее спасибо!
Когда я выключил брокера, у меня возникло исключение JMSException, которое, как я предполагал, выдается, когда я пытаюсь отправить подтверждение, потому что сообщение повторно доставляется от второго брокера. Более того, у слушателя есть счетчик входящих сообщений, и этот счетчик увеличивает свое значение, даже когда генерируется исключение.
но в этом случае все работает как надо. Это не подтверждается из-за отключения брокера. Или я что-то упускаю?
Если вы просмотрите код слушателя, я представил вызов message.acknowledge (); Я предполагал, что это немедленно отправит подтверждение.
Я предполагаю, что когда генерируется исключение JMSException, оно не знает.
Вам следует рассмотреть возможность использования Transaction с JmsListener, чтобы иметь транзакционную семантику.
Извини, Саймон, возможно, я неправильно объяснил свою ситуацию. Я отлаживаю свое приложение и уверен, что получаю сообщение, но когда я вызываю метод подтверждения, сообщение не удаляется из очереди. Я думаю, что в режиме подтверждения клиента так и должно быть.
JmsListener использует AUTO_ACKNOWLEDGE, поэтому он должен быть подтвержден, НО если выдается исключение JMSException, оно не будет подтверждено.
Спасибо! Это имеет смысл в моей ситуации. Я попробую без JmsListener.
Можно ли изменить настройку режима подтверждения объекта factroy слушателя ?? Я попробовал ввести свой код, но это не сработало.
Если вы используете транзакцию, вам не нужно устанавливать режим подтверждения. Прочтите API Doc docs.spring.io/spring-framework/docs/current/javadoc-api/org /…
Мне нужно установить режим подтверждения и отсутствие транзакции, потому что я не хочу обрабатывать сообщение, если я не могу отправить acknoledege из-за ошибки подключения.
И для этого нужны транзакции ...




как вы думаете, почему сообщение было обработано? Нет ли исключения, когда вы закрываете одного брокера?