1. 报错内容
报错: Channel shutdown: channel error;
protocol method: #method<channel.close>(
reply-code=406,
reply-text=PRECONDITION_FAILED - inequivalent arg 'x-message-ttl'
for queue 'door_queue'
in vhost '/':
received '300000' but current is none,
class-id=50, method-id=10)
这报错内容的意思是:
对于虚拟机‘/’下的队列door_queue
,接收到参数x-messsage-ttl=300000
,但是当前这个参数为none(也就是没找到这个参数)
2. 服务器查看
- 进入对应用户对应
vhost
下的queue
界面,找到报错的队列door_queue
;
- 查看队列
door_queue
的参数(这是已经重新添加了参数的)原本是没有参数x-message-ttl
参数的,所以才会报错为none
。
3. 检查代码
IDEA工具全局搜索相关报错内容中出现的关键词,比如door_queue
。发现以下代码:
//队列名称
public final static String doorQueue = "door_queue";
//死信 routingKey
public final static String deadRoutingKeyDoor = "dead_routing_key_door";
//死信队列 交换机标识符
public static final String DEAD_LETTER_QUEUE_KEY = "x-dead-letter-exchange";
//死信队列交换机绑定键标识符
public static final String DEAD_LETTER_ROUTING_KEY = "x-dead-letter-routing-key";
@Bean
public Queue doorQueue() {
Map<String, Object> args = new HashMap<>(2);
// 设置死信的交换机
args.put(DEAD_LETTER_QUEUE_KEY, dealExchangeDoor);
//直接设置 Queue 延迟时间 但如果直接给队列设置过期时间,这种做法不是很灵活
args.put("x-message-ttl", 5 * 1000 *60);
// 设置死信队列的消费队列
args.put(DEAD_LETTER_ROUTING_KEY, deadRoutingKeyDoor);
// 创建死信队列
return new Queue(RabbitMQConfiguration.doorQueue, true, false, false, args);
}
这是定义一个新队列,队列绑定一个死信交换机,并指定routing_key
,这一步导致项目每次启动会去new
一个queue
;
但是已经存在了一个相同名字的队列door_queue
,没有属性x-message-ttl
。
队列是不可变的;创建它们后,将无法更改它们的属性。所以只能删除队列door_queue
。
4 解决
以下方法选择其一:
- 删除出错的队列,重新运行代码,MQ会自动重新建一个带参队列(推荐)。
- 手动在MQ建一个带需求参数的队列。