RabbitMQ存在autodelete为false的队列时重启抛出绑定错误如何解决
问题现象
当RabbitMQ中存在auto-delete属性为false的队列时,每次重启服务都会抛出绑定错误,错误日志如下:
2021-10-25T17:59:58.438-0600 ERROR [rabbitmqWorkerImportantListenerContainer-7329] RMQSession - RabbitMQ exception on queue declare name(Tasks), durable(true), exclusive(false), auto-delete(false), properties(null) java.io.IOException: null at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:129) at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:125) at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:147) at com.rabbitmq.client.impl.ChannelN.queueBind(ChannelN.java:1077) at com.rabbitmq.client.impl.recovery.AutorecoveringChannel.queueBind(AutorecoveringChannel.java:393) at com.rabbitmq.jms.client.RMQSession.declareRMQQueue(RMQSession.java:940) at com.rabbitmq.jms.client.RMQSession.createQueue(RMQSession.java:863) at jdk.internal.reflect.GeneratedMethodAccessor101.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no binding Tasks between exchange 'jms.durable.queues' in vhost '/' and queue 'Tasks' in vhost '/', class-id=50, method-id=20) at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66) at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:36) at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:502) at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:293) at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:141) ... 18 common frames omitted
根因分析
错误日志中的
reply-code=404, reply-text=NOT_FOUND - no binding Tasks between exchange 'jms.durable.queues' in vhost '/' and queue 'Tasks' in vhost '/'直接指向绑定缺失问题,而非队列不存在。
- 报错核心原因是:队列
Tasks本身存在,但它和RabbitMQ JMS客户端内置的持久化队列专用交换机jms.durable.queues之间的绑定关系丢失了 - 绑定丢失通常有两个触发条件:
- 首次创建队列时未同步创建绑定,或者创建的绑定为非持久化属性,RabbitMQ重启后非持久化绑定会被自动清空
- JMS客户端配置关闭了自动声明绑定的开关,服务重启声明队列时不会自动补全缺失的绑定
解决方案
- 永久修复方案
- 手动补全持久化绑定,执行命令:
rabbitmqctl bind_queue --vhost / Tasks jms.durable.queues Tasks,该绑定为持久化属性,RabbitMQ重启后不会丢失 - 修改JMS客户端配置,开启
declaredBindings=true参数,后续服务重启声明队列时会自动检查并补全缺失的绑定
- 手动补全持久化绑定,执行命令:
- 紧急恢复方案
若生产环境需要快速恢复服务,且确认队列Tasks中无未消费的重要业务消息,可直接删除该队列后重启服务,客户端会自动重新创建队列和对应的持久化绑定
内容的提问来源于stack exchange,提问作者ramvirsingh
相关产品推荐
相关产品推荐

