ActiveMQ Artemis: обработка отказа клиента для независимых серверов без встроенного протокола переключения при отказе отJAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 ActiveMQ Artemis: обработка отказа клиента для независимых серверов без встроенного протокола переключения при отказе от

Сообщение Anonymous »

TL;DR:
Я перехожу с ActiveMQ Classic на ActiveMQ Artemis, и мне нужно вручную обрабатывать аварийное переключение клиента между двумя независимыми серверами. Протокол аварийного переключения: из ActiveMQ Classic недоступен в Artemis. Как я могу реализовать аварийное переключение на уровне приложения с помощью ExceptionListener, чтобы добиться автоматического повторного подключения клиента, как это происходило в ActiveMQ Classic? У нас есть ограничение: оба брокера работают как встроенные в приложение, так и независимо. Невозможно определить кластер или основной и резервный брокер, как описано здесь.
Полный контекст:
Я нахожусь в процессе миграции от ActiveMQ Classic до ActiveMQ Artemis. Наша установка состоит из двух автономных приложений Spring Boot, каждое из которых имеет встроенный брокер Artemis, работающий независимо на сервере1 и сервере2.

Конфигурация классического клиента ActiveMQ:
В ActiveMQ Classic мы использовали протокол аварийного переключения: для автоматической обработки повторных подключений клиентов при выходе из строя одного или обоих серверов. URL-адрес брокера был настроен следующим образом:
[code]import org.apache.activemq.ActiveMQConnectionFactory;

@Bean
public ConnectionFactory connectionFactory(String user, String credential) {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("failover:(tcp://server1:port1,tcp://server2:port2)?jms.useAsyncSend=true&initialReconnectDelay=100&timeout=2000&randomize=false");
factory.setTrustAllPackages(true);
factory.setUserName(user);
factory.setPassword(credential);
return factory;
}
[/code]
Конфигурация клиента ActiveMQ Artemis:

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

Код: Выделить всё

import org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory;

public ConnectionFactory connectionFactory(String user, String credential) {
ActiveMQJMSConnectionFactory factory = new ActiveMQJMSConnectionFactory("(tcp://server1:port1,tcp://server2:port2)?jms.useAsyncSend=true&initialReconnectDelay=100&timeout=2000&sslEnabled=false&failoverAttempts=-1&useTopologyForLoadBalancing=false&connectionLoadBalancingPolicyClassName=org.apache.activemq.artemis.api.core.client.loadbalance.FirstElementConnectionLoadBalancingPolicy", user, credential);
return factory;
}

Проблема.

Мы стремимся реализовать аварийное переключение на уровне приложения вручную, как описано здесь. Наша цель — перехватить события отключения и попытаться выполнить повторное подключение программным способом.
Проблема 1: первоначальное переключение соединения
Когда сервер1 не работает, клиент не пытается автоматически подключиться к серверу2, и выдается следующее исключение:

Код: Выделить всё

org.springframework.jms.UncategorizedJmsException: Uncategorized exception occurred during JMS processing; nested exception is ActiveMQNotConnectedException[errorType=NOT_CONNECTED message=AMQ219007: Cannot connect to server(s). Tried with all available servers.]
Проблема 2. Обработка отключений и повторных подключений
Когда клиент подключается к серверу1, а сервер1 отключается, соединение потеряно, и клиент не пытается повторно подключиться к серверу2. Прослушиватель исключений вызывается только после server1 резервного копирования.

Код: Выделить всё

2024-07-29 10:12:45,318 [Thread-0 (ActiveMQ-client-global-threads)] INFO   o.a.a.a.c.client [] - AMQ214036: Connection closure to server1/server1:port1 has been detected: AMQ219015: The connection was disconnected because of server shutdown [code=DISCONNECTED]
2024-07-29 10:13:09,546 [Thread-6] INFO   d.d.m.j.ExampleListener [] - received exception in topic listener: {}
jakarta.jms.JMSException: ActiveMQDisconnectedException[errorType=DISCONNECTED message=AMQ219015: The connection was disconnected because of server shutdown]
2024-07-29 11:32:29,339 [Thread-6] INFO   d.d.m.j.ExampleListener [] - received exception in topic listener: {}
jakarta.jms.JMSException: ActiveMQDisconnectedException[errorType=DISCONNECTED message=AMQ219015: The connection was disconnected because of server shutdown]
at org.apache.activemq.artemis.jms.client.ActiveMQConnection$JMSFailureListener.connectionFailed(ActiveMQConnection.java:724) ~[artemis-jakarta-client-2.33.0.jar:2.33.0]
at org.apache.activemq.artemis.jms.client.ActiveMQConnection$JMSFailureListener.connectionFailed(ActiveMQConnection.java:745) ~[artemis-jakarta-client-2.33.0.jar:2.33.0]
at org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl.callSessionFailureListeners(ClientSessionFactoryImpl.java:878) ~[artemis-core-client-2.33.0.jar:2.33.0]
at org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl.callSessionFailureListeners(ClientSessionFactoryImpl.java:866) ~[artemis-core-client-2.33.0.jar:2.33.0]
at org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl.failoverOrReconnect(ClientSessionFactoryImpl.java:812) ~[artemis-core-client-2.33.0.jar:2.33.0]
at org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl.handleConnectionFailure(ClientSessionFactoryImpl.java:576) ~[artemis-core-client-2.33.0.jar:2.33.0]
at org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl$DelegatingFailureListener.connectionFailed(ClientSessionFactoryImpl.java:1417) ~[artemis-core-client-2.33.0.jar:2.33.0]
at org.apache.activemq.artemis.spi.core.protocol.AbstractRemotingConnection.callFailureListeners(AbstractRemotingConnection.java:98) ~[artemis-core-client-2.33.0.jar:2.33.0]
at org.apache.activemq.artemis.core.protocol.core.impl.RemotingConnectionImpl.fail(RemotingConnectionImpl.java:209) ~[artemis-core-client-2.33.0.jar:2.33.0]
at org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl$CloseRunnable.run(ClientSessionFactoryImpl.java:1182) ~[artemis-core-client-2.33.0.jar:2.33.0]
at org.apache.activemq.artemis.utils.actors.OrderedExecutor.doTask(OrderedExecutor.java:57) ~[artemis-commons-2.33.0.jar:2.33.0]
at org.apache.activemq.artemis.utils.actors.OrderedExecutor.doTask(OrderedExecutor.java:32) ~[artemis-commons-2.33.0.jar:2.33.0]
at org.apache.activemq.artemis.utils.actors.ProcessorBase.executePendingTasks(ProcessorBase.java:68) ~[artemis-commons-2.33.0.jar:2.33.0]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?]
at org.apache.activemq.artemis.utils.ActiveMQThreadFactory$1.run(ActiveMQThreadFactory.java:118) ~[artemis-commons-2.33.0.jar:2.33.0]
Caused by: org.apache.activemq.artemis.api.core.ActiveMQDisconnectedException: AMQ219015: The connection was disconnected because of server shutdown
...  7 more

2024-07-29 11:32:29,351 [Thread-6] WARN   d.d.m.j.ExampleListener [] - Exception is not an instance of ActiveMQDisconnectedException
Вот реализация нашего ExceptionListener:

Код: Выделить всё

public class ExampleListener implements ExceptionListener {

private static final Logger LOG = LoggerFactory.getLogger(ExampleListener.class);

@Override
public void onException(final JMSException exception) {
LOG.info("Received exception in topic listener: {}", exception);

if (exception.getLinkedException() instanceof ActiveMQDisconnectedException) {
// This if-Statement is always false.
ActiveMQDisconnectedException e = (ActiveMQDisconnectedException) exception.getLinkedException();
LOG.info("Disconnected exception type: {}", e.getType());
LOG.info("Disconnected message type: {}", e.getMessage());
// Handle reconnection logic here
} else {
LOG.warn("Exception is not an instance of ActiveMQDisconnectedException");
}
}
}

Вопросы:

  • Как мы можем обрабатывать повторное подключение, если прослушиватель исключений вызывается только после > сервер перезапущен?
    Как мы можем программно определить, какой сервер не работает, и попытаться повторно подключиться к другому серверу, аналогично поведению при отказе: в ActiveMQ Classic? li>
Будем очень признательны за любые рекомендации по обеспечению надежного переключения клиента при сбое в ActiveMQ Artemis.


Подробнее здесь: https://stackoverflow.com/questions/788 ... hout-built
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»