spring amqp rabbit max消费者连接重试

时间:2017-02-21 20:16:25

标签: spring-amqp

我正在尝试确定从我的应用程序到兔子经纪人的最大重试次数。 我有重试拦截器,

@Bean
public RetryOperationsInterceptor retryOperationsInterceptor() {
    return RetryInterceptorBuilder.stateless()
            .maxAttempts(CommonConstants.MAX_AMQP_RETRIES)
            .backOffOptions(500, 2.0, 3000)
            .build();
}

,这在侦听器容器中使用,

container.setAdviceChain(new Advice[]{retryOperationsInterceptor()});

但是,经过几次重试后,消费者会在无限循环中再次尝试连接,

2017-02-21 15:03:12.229  WARN 9292 --- [nsumerThread_92]  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: connect
2017-02-21 15:03:12.229  INFO 9292 --- [nsumerThread_92] o.s.a.r.l.SimpleMessageListenerContainer : Restarting Consumer: tags=[{}], channel=null, acknowledgeMode=AUTO local queue size=0
2017-02-21 15:03:13.245  WARN 9292 --- [nsumerThread_93] 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: connect
2017-02-21 15:03:13.245  INFO 9292 --- [nsumerThread_93] o.s.a.r.l.SimpleMessageListenerContainer : Restarting Consumer: tags=[{}], channel=null, acknowledgeMode=AUTO local queue size=0
2017-02-21 15:03:13.261 ERROR 9292 --- [nsumerThread_83] o.s.a.r.l.SimpleMessageListenerContainer : Failed to check/redeclare auto-delete queue(s).

我希望应用程序失败并因为在MAX_RETRY#limit之后缺少与代理的连接而输出错误。

感谢您的帮助

EDIT

根据@ artem-bilan的建议,我最终使用Component

public class BrokerFailureEventListener implements ApplicationListener<ListenerContainerConsumerFailedEvent>

在这个班级onApplicationEvent我计算了失败次数,然后采取适当的行动。

在生产者方面,情况略有不同。正如@ artem-bilan所解释的那样,该应用程序需要处理任何问题。我探索了使用netflix-hystrix并为生产方法添加了fallback方法,并将采用该路线。再次感谢。

1 个答案:

答案 0 :(得分:1)

嗯,你误解了一点container.setAdviceChain(new Advice[]{retryOperationsInterceptor()});。它是针对消息处理过程中的业务错误:

  

与协议错误和连接断开相反,业务异常处理可能需要更多考虑和一些自定义配置,尤其是在使用事务和/或容器时。在2.8.x之前,RabbitMQ没有死信行为的定义,因此默认情况下,由于业务异常而被拒绝或回滚的消息可以无限制地重新传递。为了在客户端限制重新传递的数量,一个选择是在侦听器的建议链中的StatefulRetryOperationsInterceptor。拦截器可以有一个恢复回调来实现自定义死信操作:适合您特定环境的任何内容。

与:

相矛盾
  

事实上,它无休止地试图重新启动消费者,并且只有消费者表现得非常糟糕,才会放弃。一个副作用是,如果代理在容器启动时关闭,它将继续尝试直到可以建立连接。

您需要的是ListenerContainerConsumerFailedEvent,其发布方式为:

private void logConsumerException(Throwable t) {
        if (logger.isDebugEnabled()
                || !(t instanceof AmqpConnectException  || t instanceof ConsumerCancelledException)) {
            logger.warn(
                    "Consumer raised exception, processing can restart if the connection factory supports it",
                    t);
        }
        else {
            logger.warn("Consumer raised exception, processing can restart if the connection factory supports it. "
                    + "Exception summary: " + t);
        }
        publishConsumerFailedEvent("Consumer raised exception, attempting restart", false, t);
    }

因此,您可以监听这些事件并在达到某些条件时停止您的应用程序。