我有两个应用程序使用相同的spring-amqp
和spring-cloud-stream
配置。但是,当其中一个 rabbitmq 群集节点出现故障时,一个应用程序正在重新声明匿名队列,而第二个应用程序将失败。我在日志中发现的唯一区别是 amqqueue 日志中的附加布尔值。应用程序启动期间的整个声明用作超级按钮。唯一的问题是注册队列的 rabbitmq 节点何时关闭。
== 工作应用程序 ==
spring: Auto-declaring a non-durable, auto-delete, or exclusive Queue (myQueueName.anonymous.A6dm37UlRsisaftuN8SwkQ) durable:false, auto-delete:true, exclusive:true. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.
rabbit: 2019-08-13 00:27:02.636 [debug] <0.1241.0> Supervisor {<0.1241.0>,rabbit_amqqueue_sup} started rabbit_prequeue:start_link({amqqueue,{resource,<<"/">>,queue,<<"myQueueName.anonymous.A6dm37UlRsisaftuN8SwkQ">>},false,...}, declare, <0.1240.0>) at pid <0.1242.0>
== 应用程序失败 ==
spring: Auto-declaring a non-durable, auto-delete, or exclusive Queue (myQueueName.anonymous.-6He5tcQSB2Bk17EIiay3g) durable:false, auto-delete:true, exclusive:true. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.
rabbit: 2019-08-13 00:24:07.097 [debug] <0.2922.0> Supervisor {<0.2922.0>,rabbit_amqqueue_sup} started rabbit_prequeue:start_link({amqqueue,{resource,<<"/">>,queue,<<"myQueueName.anonymous.-6He5tcQSB2Bk17EIiay3g">>},false,true,...}, declare, <0.2921.0>) at pid <0.2923.0>
rabbit: operation queue.declare caused a channel exception not_found: no queue 'myQueueName.anonymous.-6He5tcQSB2Bk17EIiay3g' in vhost '/'
如果您为queue_declare
方法设置passive
标志,则此问题的另一个原因:
https://www.rabbitmq.com/amqp-0-9-1-reference.html#queue.declare.passive
它希望有人已经创建了一个队列。 取消设置标志或使用应用的其他组件创建队列。
最后,我意识到这两个应用程序之间的区别在于,第一个应用程序既是生产者,也是生产者。如果应用程序只是一个消费者并且不包含生产者定义,则在代理重新启动期间由 spring 处理的交换重新声明将失败(即使交换在此操作之前已在节点上正确注册)。在使用者属性中设置declareExchange=false
解决了该问题。