RabbitMQ中的队列类型包括:
1、普通队列: 标准的消息队列。
2、优先级队列: 支持消息优先级。
3、死信队列: 存储无法处理的消息。
在 RabbitMQ (结合 Spring Boot) 中,队列的“种类”本质上是通过在声明队列时传入不同的属性参数(Arguments)来实现的。
下面我将分别给出这三种队列的代码定义方式及核心原理解释。
定义:最基础的消息队列,遵循先进先出(FIFO)原则。
代码实现:直接使用 Queue 类的构造函数声明即可。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import org.springframework.amqp.core.Queue; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
@Configuration public class StandardQueueConfig {
public static final String STANDARD_QUEUE = "standard_queue";
@Bean public Queue standardQueue() { // 参数说明: // 1. 队列名称 // 2. durable: 是否持久化 (true: 重启后队列依然存在) return new Queue(STANDARD_QUEUE, true); } } |
定义:支持给消息打“星级”。
如果队列中有消息堆积,RabbitMQ 会优先将优先级高的消息推送给消费者,打破绝对的先进先出。
代码实现:需要在声明队列时配置 x-max-priority 属性,设定最大优先级数字。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import org.springframework.amqp.core.Queue; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
import java.util.HashMap; import java.util.Map;
@Configuration public class PriorityQueueConfig {
public static final String PRIORITY_QUEUE = "priority_queue";
@Bean public Queue priorityQueue() { Map<String, Object> args = new HashMap<>(); // 开启优先级队列,并设置最大优先级为 10(官方建议值为 1-10,最高可设置 255) args.put("x-max-priority", 10);
// 参数说明:名称, durable, exclusive(独占), autoDelete(自动删除), arguments(特殊属性) return new Queue(PRIORITY_QUEUE, true, false, false, args); } } |
生产者在发送消息时,需要手动设置消息的 priority 属性:
|
1 2 3 4 |
rabbitTemplate.convertAndSend("exchange_name", "routing_key", "紧急消息", message -> { message.getMessageProperties().setPriority(9); // 设置高优先级 return message; }); |
注意:优先级队列只有在消费者消费速度跟不上生产者发送速度,导致消息在队列中堆积时,优先级排序才会生效。如果发一条就被消费一条,是没有意义的。
定义:死信队列本质上就是个普通队列。
只是它被绑定到了一个“死信交换机 (DLX)”上。当某个正常业务队列里的消息变成了“死信”时,RabbitMQ 会自动把这些消息丢进死信交换机,最终流向死信队列,用来做异常排查或补偿机制。
代码实现:需要声明三个部分(业务队列、死信交换机、死信队列)。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
import org.springframework.amqp.core.*; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
import java.util.HashMap; import java.util.Map;
@Configuration public class DeadLetterQueueConfig {
// ==================== 1. 定义死信交换机和死信队列 ==================== public static final String DLX_EXCHANGE = "dlx_exchange"; public static final String DEAD_LETTER_QUEUE = "dead_letter_queue"; public static final String DLX_ROUTING_KEY = "dlx_routing_key";
@Bean public DirectExchange dlxExchange() { return new DirectExchange(DLX_EXCHANGE); }
@Bean public Queue deadLetterQueue() { return new Queue(DEAD_LETTER_QUEUE, true); }
@Bean public Binding dlxBinding() { return BindingBuilder.bind(deadLetterQueue()).to(dlxExchange()).with(DLX_ROUTING_KEY); }
// ==================== 2. 定义普通业务队列 (并绑定死信机制) ==================== public static final String BUSINESS_QUEUE = "business_queue";
@Bean public Queue businessQueue() { Map<String, Object> args = new HashMap<>(); // 核心配置:当这个业务队列出现死信时,交给哪个死信交换机处理 args.put("x-dead-letter-exchange", DLX_EXCHANGE); // 核心配置:发给死信交换机时,带上什么路由键 args.put("x-dead-letter-routing-key", DLX_ROUTING_KEY);
// 为了演示触发死信,我们给这个业务队列加一个最大长度限制 // 如果队列堆积超过 5 条,第 6 条就会变成死信,进入 dead_letter_queue args.put("x-max-length", 5);
return new Queue(BUSINESS_QUEUE, true, false, false, args); } } |
Business Queue (塞不进去了)→ 死信交换机 → Dead Letter Queue
| 队列类型 | Spring AMQP 定义方式 | 核心依赖的 Argument (参数) | 主要应用场景 |
| 普通队列 | new Queue("name") | 无特殊参数 | 常规异步解耦、削峰填谷 |
| 优先级队列 | new Queue(..., args) | x-max-priority | VIP客户订单优先处理、加急短信发送 |
| 死信队列 | new Queue(..., args) |
x-dead-letter-exchange x-dead-letter-routing-key |
异常消息兜底、延迟队列基础、消息防丢失处理 |