主题
spring amqp rabbitmq容器在运行中会根据异常等级(Fatal)认为不可恢复,重试后会关闭。本文分享导致关闭的一个场景,以及如何配置来恢复连接。
异常日志
Cancel received for ***
Consumer raised exception, processing can restart if the connection factory supports it. Exception summary: org.springframework.amqp.rabbit.support.ConsumerCancelledException
Restarting Consumer:
Failed to check/redeclare auto-delete queue(s). org.springframework.amqp.AmqpIOException: java.io.IOException
Failed to declare queue
Queue declaration failed; retries left=3 org.springframework.amqp.rabbit.listener.BlockingQueueConsumer$DeclarationException: Failed to declare queue(s): xxx_queue
Consumer received fatal exception on startup org.springframework.amqp.rabbit.listener.QueuesNotAvailableException: Cannot prepare queue for listener. Either the queue doesn't exist or the broker will not allow us to use it.
at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:539)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.
Stopping container from aborted consumer
问题说明
spring amqp rabbitmq 使用中遇到 rabbitmq服务端因为某些问题,比如重启(生产一般很少发生),权限配置错误,误操作(误删队列)等导致服务端短期连接不上时,org.springframework.amqp:spring-rabbit:1.7.8.RELEASE (2.0版本可能也是,未测试),默认采取的策略是重试3次(Queue declaration failed; retries left=3 ),每次相隔5秒。如果仍然连接不上,并且当前rabbitmq container 没有其他队列的情况,则会关闭(Stopping container from aborted consumer)。即使rabbitmq server恢复之后(以上种种误操作),是不会重连,并继续消费的。
正确配置
@Bean(name ="xxxContainerFactory")
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(SimpleRabbitListenerContainerFactoryConfigurer configurer,
@Qualifier("xxxConnectionFactory")ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory =new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setAcknowledgeMode(AcknowledgeMode.AUTO);
factory.setPrefetchCount(1);
factory.setRecoveryInterval(5000L);
factory.setMissingQueuesFatal(false);
configurer.configure(factory,connectionFactory);
return factory;
}
设置factory.setMissingQueuesFatal(false),其中missingQueuesFatal.设置为true(默认值)时,如果 broker 上的 none 配置队列可用,则认为它是致命的。这会导致 application context 在启动期间无法初始化;此外,当容器正在运行时删除队列时,默认情况下,消费者进行 3 次重试以连接到队列(间隔为 5 秒)并在这些尝试失败时停止容器。
在以前的版本中无法配置。
设置为false时,在进行 3 次重试后,容器将进入恢复模式,与其他问题一样,例如 broker 已关闭。容器将尝试根据recoveryInterval property 进行恢复。在每次恢复尝试期间,每个 consumer 将再次尝试 4 次以 5 秒间隔被动地声明队列。这个 process 将无限期地继续。
配置介绍
更多其他配置项含义官方有详细说明。
英语(官方):
https://docs.spring.io/spring-amqp/reference/html/#containerAttributes
中文:
https://www.docs4dev.com/docs/zh/spring-amqp/1.7.11.RELEASE/reference/_reference.html
网友评论