Как настроить автоматическое аварийное переключение клиента с помощью Apache Artemis MQ и Spring Jms - PullRequest
0 голосов
/ 03 апреля 2019

Я настраиваю инфраструктуру высокой доступности с помощью 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

...