Я настраиваю инфраструктуру высокой доступности с помощью Apache Artemis MQ 2.6.3 и Spring Jms. Как настроить автоматическое аварийное переключение клиента с ActiveMQConnectionFactory?
Существует два экземпляра Apache Artemis 2.6.3, один действующий и один резервный узел. Когда прямая трансляция не работает, резервная копия будет активной и будет обслуживать клиентов. Когда живой сервер снова работает, он получает соединения. Мне удалось настроить эти MQ-серверы, они работают так, как я ожидаю.
Но когда я использую Spring JmsTemplate для создания сообщений, он перестает работать, когда живой сервер не работает.
Согласно документации Артемиды (https://activemq.apache.org/artemis/docs/latest/ha.html):
«Чтобы включить автоматическое переключение при сбое клиента, клиент должен быть настроен на разрешение ненулевых попыток переподключения»
Но клиент вообще не делал автоматического перехода на другой ресурс.
Вот конфигурация:
@EnableJms
@Configuration
public class ArtemisConnectionConfiguration {
@Bean
public MessageConverter artemisMessageConverter() {
return new SimpleMessageConverter();
}
@Bean
public ConnectionFactory artemisConnectionFactory(ArtemisConnectionProperties properties) {
TransportConfiguration masterTransportConfiguration = createTransportConfiguration(properties);
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(true, masterTransportConfiguration);
if (StringUtils.isNotBlank(properties.getUser())) {
connectionFactory.setUser(properties.getUser());
connectionFactory.setPassword(properties.getPassword());
}
connectionFactory.setInitialConnectAttempts(properties.getInitialConnectAttempts());
connectionFactory.setClientFailureCheckPeriod(properties.getClientFailureCheckPeriod());
return connectionFactory;
}
@Bean
public JmsTemplate artemisTemplate(
@Qualifier("artemisMessageConverter") MessageConverter messageConverter,
@Qualifier("artemisConnectionFactory") ConnectionFactory connectionFactory) {
JmsTemplate template = new JmsTemplate(connectionFactory);
template.setMessageConverter(messageConverter);
return template;
}
@Bean
public JmsListenerContainerFactory artemisListener(
@Qualifier("artemisMessageConverter") MessageConverter messageConverter,
@Qualifier("artemisConnectionFactory") ConnectionFactory connectionFactory) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setMessageConverter(messageConverter);
return factory;
}
private TransportConfiguration createTransportConfiguration(ArtemisConnectionProperties properties) {
Map<String, Object> params = new HashMap<>();
params.put(TransportConstants.HOST_PROP_NAME, properties.getHost());
params.put(TransportConstants.PORT_PROP_NAME, properties.getPort());
return new TransportConfiguration(NettyConnectorFactory.class.getName(), params);
}
}
В режиме отладки я вижу, что у ConnectionFactory есть адрес резервного узла, чтобы он мог получить топологию с живого сервера. Когда прямая трансляция не работает, клиент пытается подключиться, но только к работающему серверу.
Что я сделал не так?
Вот пример приложения: https://github.com/almaxbacsi/artemis-ha-test