队列名和 vhost 名统一替换为占位符 <QUEUE>
和 <VHOST>
:
问题
inequivalent arg 'durable' for queue '<QUEUE>' in vhost '<VHOST>': received 'true' but current is 'false'
- 当前(已有)的队列
<QUEUE>
在 RabbitMQ 中被创建时是durable=false
(非持久化)。 - 而这次客户端执行
queue.declare
时却指定了durable=true
(持久化)。 - 因为属性不一致,RabbitMQ 触发了 “前置条件失败”(
precondition_failed
),并关闭了该 channel。
原因分析
-
队列属性冲突
同名队列的durable
、exclusive
、auto_delete
及任何自定义arguments
都必须一致,任何不符都会导致PRECONDITION_FAILED
并断开 channel。 -
执行流程
- 应用先正常连接到 vhost
<VHOST>
; - 然后执行
queue.declare(queue="<QUEUE>", durable=true, …)
; - RabbitMQ 对比发现已有队列属性为
durable=false
,抛出错误并关闭该 channel。
- 应用先正常连接到 vhost
仲裁队列没有持久化这个选项,默认是持久化的
解决办法
-
统一声明参数
确保所有地方对<QUEUE>
的声明参数一致:# 如果需要持久化 channel.queue_declare(queue="<QUEUE>", durable=True) # 否则全部设为 False channel.queue_declare(queue="<QUEUE>", durable=False)
-
删除并重建队列
如果已有队列参数不对,可先删除再用正确参数重建:# 删除占位队列 rabbitmqadmin -u USER -p PASS -V <VHOST> delete queue name=<QUEUE> # 用正确参数重新创建 rabbitmqadmin -u USER -p PASS -V <VHOST> declare queue name=<QUEUE> durable=true
-
被动检查
只想校验属性时,可用被动声明:channel.queue_declare(queue="<QUEUE>", passive=True)
被动声明不会修改队列,只检查其存在及属性,否则抛错。
小结:将所有声明中的 <QUEUE>
和 <VHOST>
参数统一,或删除旧队列后重新创建,即可消除 inequivalent arg 'durable'
错误。