Обработка ошибок SimpleMessageListenerContainer

Я использую SimpleMessageListenerContainer в качестве основы для удаленного взаимодействия через AMQP. Все идет гладко при условии, что брокер RabbitMQ доступен при запуске процесса. Однако, если по какой-либо причине он недоступен (сеть не работает, проблемы с разрешениями и т. д.), контейнер просто продолжает повторять попытки подключения навсегда. Как в этом случае настроить поведение повторных попыток (например, попытаться максимум 5 раз с экспоненциальной отсрочкой, а затем прервать, убив процесс)? Я просмотрел это, но это не так. кажется, работает для меня при запуске контейнера. Кто-нибудь может пролить свет?

По крайней мере, я хотел бы иметь возможность поймать исключение и предоставить сообщение журнала вместо того, чтобы печатать само исключение, как это делается по умолчанию.


person Martin    schedule 05.02.2015    source источник
comment
Не могли бы вы поделиться StackTrace по этому вопросу? Для retry потребительского запуска такой опции нет. Это Advice[] для целевого слушателя - бизнес-операция, а не технический запуск.   -  person Artem Bilan    schedule 05.02.2015


Ответы (1)


Как я могу настроить поведение повторной попытки в этом случае

Нет сложной повторной попытки подключения, просто recoveryInterval. Предполагается, что недоступность брокера носит временный характер. Неустранимые ошибки (например, неверные учетные данные) останавливают контейнер.

Вы можете использовать какой-нибудь внешний процесс, чтобы попробовать connectionFactory.createConnection() и stop() SimpleMessageListenerContainer, когда сочтете, что пришло время сдаться.

Вы также можете создать подкласс CachingConnectionFactory, переопределить createBareConnection, перехватить исключение и увеличить recoveryInterval, а затем вызвать stop(), когда захотите.

ИЗМЕНИТЬ

Начиная с версии 1.5 теперь вы можете настроить отсрочку. Вот пример использования Spring Boot...

@SpringBootApplication
public class RabbitBackOffApplication {

    public static void main(String[] args) {
        SpringApplication.run(RabbitBackOffApplication.class, args);
    }

    @Bean(name = "rabbitListenerContainerFactory")
    public SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory(
            SimpleRabbitListenerContainerFactoryConfigurer configurer,
            ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        BackOff recoveryBackOff = new FixedBackOff(5000, 3);
        factory.setRecoveryBackOff(recoveryBackOff);
        return factory;
    }

    @RabbitListener(queues = "foo")
    public void listen(String in) {

    }

}

и

2018-04-16 12:08:35.730  INFO 84850 --- [           main] com.example.RabbitBackOffApplication     : Started RabbitBackOffApplication in 0.844 seconds (JVM running for 1.297)
2018-04-16 12:08:40.788  WARN 84850 --- [cTaskExecutor-1] o.s.a.r.l.SimpleMessageListenerContainer : Consumer raised exception, processing can restart if the connection factory supports it. Exception summary: org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused (Connection refused)
2018-04-16 12:08:40.788  INFO 84850 --- [cTaskExecutor-1] o.s.a.r.l.SimpleMessageListenerContainer : Restarting Consumer@57abad67: tags=[{}], channel=null, acknowledgeMode=AUTO local queue size=0
2018-04-16 12:08:40.789  INFO 84850 --- [cTaskExecutor-2] o.s.a.r.c.CachingConnectionFactory       : Attempting to connect to: [localhost:1234]
2018-04-16 12:08:45.851  WARN 84850 --- [cTaskExecutor-2] o.s.a.r.l.SimpleMessageListenerContainer : Consumer raised exception, processing can restart if the connection factory supports it. Exception summary: org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused (Connection refused)
2018-04-16 12:08:45.852  INFO 84850 --- [cTaskExecutor-2] o.s.a.r.l.SimpleMessageListenerContainer : Restarting Consumer@3479ea: tags=[{}], channel=null, acknowledgeMode=AUTO local queue size=0
2018-04-16 12:08:45.852  INFO 84850 --- [cTaskExecutor-3] o.s.a.r.c.CachingConnectionFactory       : Attempting to connect to: [localhost:1234]
2018-04-16 12:08:50.935  WARN 84850 --- [cTaskExecutor-3] o.s.a.r.l.SimpleMessageListenerContainer : Consumer raised exception, processing can restart if the connection factory supports it. Exception summary: org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused (Connection refused)
2018-04-16 12:08:50.935  INFO 84850 --- [cTaskExecutor-3] o.s.a.r.l.SimpleMessageListenerContainer : Restarting Consumer@2be60f67: tags=[{}], channel=null, acknowledgeMode=AUTO local queue size=0
2018-04-16 12:08:50.936  INFO 84850 --- [cTaskExecutor-4] o.s.a.r.c.CachingConnectionFactory       : Attempting to connect to: [localhost:1234]
2018-04-16 12:08:50.938  WARN 84850 --- [cTaskExecutor-4] o.s.a.r.l.SimpleMessageListenerContainer : stopping container - restart recovery attempts exhausted
person Gary Russell    schedule 05.02.2015
comment
Можно ли еще создать подкласс CachingConnectionFactory и переопределить createBareConnection? Потому что начиная с версии 1.7.4 методов Spring AMQP для создания соединения являются окончательными. Как мы могли сделать это сейчас? - person djeison; 16.04.2018
comment
Ой, моя беда - всегда было final. Однако, начиная с версии 1.5, теперь вы можете настроить recoveryBackOff, который можно использовать для достижения желаемого поведения (включая остановку контейнера, когда nextBackOff() возвращает STOP). - person Gary Russell; 16.04.2018
comment
Спасибо за ваш ответ. Знаете ли вы какой-нибудь учебник по настройке этого recoveryBackOff? Я попытался объявить bean-компонент SimpleRabbitListenerContainerFactory и установить для него FixedBackOff, но он, похоже, игнорирует мою конфигурацию maxAttempts = 3 и продолжает пытаться подключиться после многих сбоев соединения. - person djeison; 16.04.2018
comment
Если вы можете задать новый вопрос, я отвечу на него с образцом. - person Gary Russell; 16.04.2018
comment
Я отредактировал свой ответ с примером. stopping container - restart recovery attempts exhausted. - person Gary Russell; 16.04.2018
comment
Хорошо, большое спасибо за ваш пример, я следовал ему здесь, и он действительно прекратил повторные попытки подключения после достижения числа maxAttempts. Единственное, что сейчас, это то, что он продолжает пытаться запускать проверки работоспособности для RabbitMQ, что приводит к вечному org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused в моей консоли. Как мы могли бы справиться с этим, чтобы он не работал тихо? - person djeison; 16.04.2018
comment
Я задал правильный вопрос здесь: stackoverflow.com/questions/49862520/ Я признателен, если вы продолжите помогать - person djeison; 16.04.2018