我正在尝试确定从我的应用程序到兔子经纪人的最大重试次数。 我有重试拦截器,
@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
方法,并将采用该路线。再次感谢。
答案 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);
}
因此,您可以监听这些事件并在达到某些条件时停止您的应用程序。