RabbitMQ消息队列:SpringAMQP

一、什么是 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(虚拟主机) 隔离不同环境的逻辑分组

🧠 七、最佳实践建议

  1. 明确队列职责:每个队列对应一种业务消息类型,便于维护。

  2. 合理设置 prefetch:根据消费者处理能力调整,避免消息倾斜或积压。

  3. 使用虚拟主机隔离环境:开发、测试、生产使用不同的 virtual-host。

  4. 异常处理与重试:结合 Spring Retry 机制,确保消息可靠性。

  5. 监控与告警:利用 RabbitMQ Management 插件监控队列深度和消费情况。

相关推荐
文丑颜不良啊7 分钟前
LeetCode2861~2880题目解析
java·leetcode
装不满的克莱因瓶18 分钟前
设计模式之策略模式核心概念和应用场景
java·后端·设计模式·架构·系统架构·策略模式
晴天的雨.99223 分钟前
【C++】继承篇
java·开发语言·c++
SomeOtherTime29 分钟前
第 1 讲:内存布局与所有权解剖——栈帧、胖指针与“移动/拷贝”在汇编层面的真实面目
java·开发语言·汇编
qq_4069810334 分钟前
c++ lamda(三)Lambda表达式
java·前端·c++
头发还在的女程序员34 分钟前
Java在线租房系统源码解析:Spring Boot+Vue 3+UniApp房源管理与预约看房方案
java·vue.js·spring boot·租房小程序·租房系统·租房软件
FYKJ_201041 分钟前
springboot同人周边订单管理系统48955-计算机毕业设计、课程设计
java·javascript·vue.js·spring boot·django·php·课程设计
kiwixing1 小时前
GaussDB|集中式还是分布式?三把尺子选型
分布式·gaussdb
Flynn Liang1 小时前
LLM 应用安全:Prompt 注入、越权与输入输出护栏
java·人工智能·大模型·langchain4j·llm 安全·prompt 注入·guardrail
特立独行的猫A7 小时前
用仓颉语言 cj-tauri 框架,五分钟给娃做了个鸿蒙形近字游戏
java·后端·python