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 插件监控队列深度和消费情况。

相关推荐
Mark_ZP1 小时前
【锁6】AQS (AbstractQueuedSynchronizer) 核心原理详解
java
AI砖家1 小时前
多商户多租户系统架构设计文档(Java版)
java·开发语言·系统架构·多租户·多商户
发量惊人的中年网工1 小时前
SD-WAN如何赋能工业物联网?打造工厂网络远程连接和数据传输新方案
运维·网络·分布式·物联网
段一凡-华北理工大学2 小时前
AI推动工业智能化转型~系列文章05:特征工程:工业 AI 的第一生产力
数据库·人工智能·分布式·搜索引擎·特征工程·高炉智能化
落苜蓿蓝2 小时前
Java 循环中对象复用导致属性覆盖?从 JVM 内存模型讲解原因
java·jvm·python
weixin_440784112 小时前
Android基础知识汇总
android·java·android studio
布鲁飞丝2 小时前
从零实现富文本编辑器#-浏览器选区与编辑器选区模型同步
java·前端·编辑器
jun_bai2 小时前
使用java安全的移动文件
java
caishenzhibiao3 小时前
市场同步系统 同花顺期货通指标
java·c语言·c#