一、什么是 SpringAMQP?
SpringAMQP 是 Spring 官方基于 RabbitMQ 提供的消息收发模板工具,它遵循 AMQP(Advanced Message Queuing Protocol)协议,具备跨语言特性,并对 SpringBoot 实现了自动装配,极大简化了开发流程。
核心功能
| 功能模块 | 说明 |
|---|---|
| 自动声明 | 自动创建队列、交换机及其绑定关系 |
| 注解监听 | 基于 @RabbitListener 的异步消息接收 |
| RabbitTemplate | 封装的消息发送模板工具 |
🚀 二、快速入门:Hello SpringAMQP
1. 项目结构
推荐采用多模块 Maven 项目结构,便于分离生产者和消费者:
mq-demo
├── publisher # 消息发送者
└── consumer # 消息消费者
2. 引入依赖
在父工程中引入 spring-boot-starter-amqp 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
3. 配置 MQ 连接(publisher & consumer)
spring:
rabbitmq:
host: 192.168.150.101 # 虚拟机 IP
port: 5672 # 端口
virtual-host: /hmall # 虚拟主机
username: hmall # 用户名
password: 123 # 密码
📤 三、消息发送(Publisher)
在 publisher 模块中编写测试类,注入 RabbitTemplate 进行消息发送:
java
@SpringBootTest
public class SpringAmqpTest {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void testSimpleQueue() {
String queueName = "simple.queue";
String message = "hello, spring amqp!";
rabbitTemplate.convertAndSend(queueName, message);
}
}
💡 提示 :
convertAndSend方法会自动将消息序列化并发送到指定队列。
📥 四、消息接收(Consumer)
在 consumer 模块中使用 @RabbitListener 注解监听队列:
java
@Component
public class SpringRabbitListener {
@RabbitListener(queues = "simple.queue")
public void listenSimpleQueueMessage(String msg) {
System.out.println("消费者接收到消息:" + msg);
}
}
启动 consumer 服务后,监听器会自动监听队列,一旦有消息到达即触发方法执行。
⚡ 五、Work Queues 模型:多消费者竞争模式
当消息生产速度远大于消费速度时,消息会不断堆积。Work Queues 模型允许多个消费者绑定到同一队列,共同消费消息,提高处理能力。
1. 场景模拟
在控制台创建 work.queue 队列,然后模拟大量消息发送:
java
@Test
public void testWorkQueue() throws InterruptedException {
String queueName = "work.queue";
for (int i = 0; i < 50; i++) {
rabbitTemplate.convertAndSend(queueName, "hello, message_" + i);
Thread.sleep(20);
}
}
2. 多消费者监听
java
@RabbitListener(queues = "work.queue")
public void listenWorkQueue1(String msg) throws InterruptedException {
System.out.println("消费者1:" + msg);
Thread.sleep(20); // 模拟快速处理
}
@RabbitListener(queues = "work.queue")
public void listenWorkQueue2(String msg) throws InterruptedException {
System.err.println("消费者2:" + msg);
Thread.sleep(200); // 模拟慢速处理
}
3. 默认问题:平均分配
默认情况下,RabbitMQ 会轮询平均分配消息,导致处理快的消费者空闲,处理慢的消费者积压。
4. 解决方案:预取计数(Prefetch)
在 consumer 配置文件中添加:
java
spring:
rabbitmq:
listener:
simple:
prefetch: 1 # 每次只预取 1 条消息,处理完再取下一个
效果 :处理快的消费者会消费更多消息,真正做到 "能者多劳"。
📊 六、核心概念对比
| 概念 | 说明 |
|---|---|
| Queue(队列) | 存储消息的容器,消费者从中取消息 |
| Exchange(交换机) | 接收生产者消息并按规则路由到队列 |
| Binding(绑定) | 交换机和队列之间的关联关系 |
| Virtual Host(虚拟主机) | 隔离不同环境的逻辑分组 |
🧠 七、最佳实践建议
-
明确队列职责:每个队列对应一种业务消息类型,便于维护。
-
合理设置 prefetch:根据消费者处理能力调整,避免消息倾斜或积压。
-
使用虚拟主机隔离环境:开发、测试、生产使用不同的 virtual-host。
-
异常处理与重试:结合 Spring Retry 机制,确保消息可靠性。
-
监控与告警:利用 RabbitMQ Management 插件监控队列深度和消费情况。