【问题标题】:SimpleMessageListenerContainer Error HandlingSimpleMessageListenerContainer 错误处理
【发布时间】:2015-04-05 04:37:24
【问题描述】:

我使用SimpleMessageListenerContainer 作为通过 AMQP 进行远程处理的基础。只要在进程启动时可以访问 RabbitMQ 代理,一切都会顺利进行。但是,如果由于任何原因无法访问(网络故障、权限问题等),容器只会不断重试以永远连接。在这种情况下,如何设置重试行为(例如,最多尝试 5 次以指数退避然后中止,终止进程)?我看过this,但它在容器启动时似乎对我不起作用。任何人都可以解释一下吗?

至少,我希望能够捕获异常并提供日志消息,而不是像默认行为那样打印异常本身。

【问题讨论】:

  • 您介意就此事分享 StackTrace 吗? retry消费者启动没有这样的选项。 Advice[] 是针对目标监听器的——业务运营,而不是技术启动。

标签: error-handling spring-amqp


【解决方案1】:

在这种情况下如何设置重试行为

没有复杂的连接重试,只是一个简单的recoveryInterval。假设经纪人不可用是暂时的。致命错误(例如错误的凭据)会停止容器。

当您认为该放弃时,您可以使用一些外部流程来尝试 connectionFactory.createConnection()stop()SimpleMessageListenerContainer

你也可以继承CachingConnectionFactory,覆盖createBareConnection捕获异常并增加recoveryInterval,然后在需要时调用stop()

编辑

从 1.5 开始,您现在可以配置 backOff。这是一个使用 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

【讨论】:

  • 是否仍然可以继承CachingConnectionFactory 并覆盖createBareConnection?因为从 Spring AMQP 版本 1.7.4 开始,用于创建连接的方法是最终的。我们现在怎么做?
  • 哎呀-我的错-一直是final。但是,从 1.5 开始,您现在可以配置一个 recoveryBackOff 来实现所需的行为(包括在 nextBackOff() 返回 STOP 时停止容器)。
  • 感谢您的回复。你知道任何关于如何配置这个recoveryBackOff 的教程吗?我尝试声明一个SimpleRabbitListenerContainerFactory bean 并为其设置一个FixedBackOff,但它似乎忽略了我的maxAttempts = 3 配置,并在多次连接失败后继续尝试连接。
  • 如果你能提出一个新问题,我会用一个例子来回答。
  • 我用一个例子编辑了我的答案。 stopping container - restart recovery attempts exhausted.
猜你喜欢
  • 2016-03-30
  • 2020-11-07
  • 2015-06-15
  • 1970-01-01
  • 2016-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多