public Queue(
String name,
boolean durable,
boolean exclusive,
boolean autoDelete,
Map<String, Object> arguments)
分别是
- name-队列标识,名称
- durable-queue队列是否持久化,rabbit宕机重启后,queue是否能被重新加载,也就是是否持久化到磁盘中,一般开启,避免丢失。
- exclusive-是否排他,独家。queue是否只被一个客户端监听使用,且当最后一个消费者连接关闭后,删除队列。
- autoDelete-消费者监听到或者说消费队列消息后,队列是否自动删除。一般false,避免消息丢失使用ack机制。
- arguments-其他参数
arguments,额外参数很有意思 可以自己定义
队列里面的msg可以自己在argument里面定义过期时间,以及过期后出队列发送到哪里。这里的延时队列又充当了生产者的角色,消息又发给mq的交换机,再由于交换机发给其他队列。接收的队列收到的都是以及过期的消息,这种二次转发可以作为分布式事务的保证,隔一段时间后检查消息是否执行成功,保证了最终一致性。
(1)x-dead-letter-exchange:死信交换器名称,过期或被删除(因队列长度超长或因空间超出阈值)的消息可指定发送到该交换器中;
(2)x-dead-letter-routing-key:死信消息路由键,在消息发送到死信交换器时会使用该路由键,如果不设置,则使用消息的原来的路由键值;
mq保证分布式事务最终一致性,使用延时队列举例子
@Bean
public Queue orderDelayQueue() {
HashMap<String, Object> arguments = new HashMap<>();
arguments.put("x-message-ttl", 60000); // 消息过期时间 1分钟
// x-dead-letter-exchange 死信交换器名称,queue里面的消息过期后发送到指定的交换
//机,这个交换机叫做死信交换机
arguments.put("x-dead-letter-exchange", "order-event-exchange");
// 死信路由键,经死信交换器转发到指定路由的队列中,完成死信交换
// 只是个名字而且 实际上还是正常的交换机到queue。交换机只是个过滤作用,不存储大量消息。
arguments.put("x-dead-letter-routing-key", "order.release.order");
Queue queue = new Queue(
"order.delay.queue",
true,
false,
false,
arguments);
return queue;
}