📖 导读

本文基于 RuoYi-Vue 前后端分离框架,手把手完成 RabbitMQ 主题交换机 + 生产者消费者完整整合,包含全套可直接复制源码、完整业务流转流程、本地测试步骤,同时整理开发过程中 5 个高频报错及根治方案。适配 Spring AMQP3.1.x、RabbitMQ4.3.2,新手可直接复刻,快速掌握消息队列异步解耦、流量削峰核心能力。

一、RabbitMQ 整体业务流程

1.1 消息完整流转五步流程

  1. 前端发起请求:浏览器访问测试接口/test/mq/send,进入 MqTestController;
  2. 控制器调用生产者:封装订单业务消息对象,注入生产者发送方法,立刻给前端返回成功提示(异步不阻塞);
  3. 生产者投递消息:RabbitTemplate 将实体序列化为 JSON,发送至order_exchange主题交换机;
  4. 交换机路由分发:根据路由键order.create匹配绑定关系,消息存入order_queue队列;
  5. 消费者监听消费:@RabbitListener 持续监听队列,自动反序列化消息执行业务逻辑,处理完成自动 ACK 删除消息。

核心特点:生产与消费完全异步解耦,前端无需等待后端复杂业务执行,大幅提升接口响应速度。

1.2 架构流转示意图

plaintext

┌─────────────┐
│   用户/浏览器 │
└──────┬──────┘
       │ HTTP GET /test/mq/send
       ↓
┌─────────────────────────────────┐
│  MqTestController (Controller层) │
│  - 创建 OrderMessage 对象        │
│  - 调用 OrderProducer            │
│  - 立即返回响应给用户             │
└────────────────────────────────┘
             │ 调用 sendOrderMessage()
             ↓
─────────────────────────────────┐
│  OrderProducer (生产者)          │
│  - 使用 RabbitTemplate           │
│  - 序列化消息为 JSON             │
│  - 发送到 order_exchange 交换机   │
────────────┬────────────────────┘
             │ 交换机路由
             ↓
─────────────────────────────────┐
│  RabbitMQ Server                │
│  ┌──────────────────────────┐   │
│  │  order_exchange (交换机)  │   │
│  │  路由键: order.create     │   │
│  └──────────┬───────────────┘   │
│             │                    │
│             ↓                    │
│  ┌──────────────────────────┐   │
│  │  order_queue (队列)       │   │
│  │  存储待消费的消息          │   │
│  └──────────┬───────────────┘   │
└────────────┬────────────────────┘
             │ 消费者监听
             ↓
─────────────────────────────────┐
│  OrderConsumer (消费者)          │
│  - @RabbitListener 监听队列      │
│  - 自动反序列化 JSON 为对象      │
│  - 执行业务逻辑                  │
│  - 发送 ACK 确认                 │
└─────────────────────────────────┘

1.3 核心组件通俗对照表

表格

技术术语 生活类比 代码对应类 / 变量 核心作用
生产者 寄件人 OrderProducer 封装业务消息并投递至 MQ
消息 快递包裹 OrderMessage 承载订单、商品等业务数据
交换机 快递分拣中心 order_exchange 根据路由键分发消息
路由键 快递地址标签 order.create 绑定交换机与队列的匹配标识
队列 快递货架 order_queue 临时存储待消费消息
消费者 快递派送员 OrderConsumer 拉取消息执行业务逻辑
ACK 确认 签收回执 自动触发 告知 MQ 消息处理完成,删除消息

二、项目目录结构

plaintext

ruoyi-system/
├── src/main/java/com/ruoyi/system/mq/
│   ├── config/
│   │   └── RabbitMQConfig.java      # MQ交换机、队列、转换器配置
│   ├── message/
│   │   └── OrderMessage.java        # 消息实体类
│   ├── producer/
│   │   └── OrderProducer.java       # 消息生产者
│   └── consumer/
│       └── OrderConsumer.java       # 消息消费者
ruoyi-admin/
├── src/main/java/com/ruoyi/web/controller/test/
│   └── MqTestController.java        # 测试接口控制器
├── src/main/resources/
│   └── application.yml               # RabbitMQ连接配置

三、完整源码实现

3.1 application.yml 连接配置

yaml

spring:
  rabbitmq:
    host: localhost              # RabbitMQ服务地址
    port: 5672                   # AMQP通信端口(管理后台15672区分)
    username: guest
    password: guest
    virtual-host: /
    listener:
      simple:
        acknowledge-mode: auto   # 自动消息确认
        concurrency: 1           # 初始消费线程
        max-concurrency: 10      # 最大并发消费线程

配置说明:

  1. 生产环境务必修改 guest 默认账号密码,提升安全性;
  2. concurrency、max-concurrency 可根据业务消息并发量调整;
  3. auto 自动 ACK:消费方法执行无异常则自动告知 MQ 删除消息。

3.2 RabbitMQConfig 核心配置类

java

package com.ruoyi.system.mq.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.support.converter.DefaultJackson2JavaTypeMapper;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMQConfig {

    // 1. 声明主题交换机
    @Bean
    public TopicExchange orderExchange() {
        // 参数:交换机名称、持久化、不自动删除
        return new TopicExchange("order_exchange", true, false);
    }

    // 2. 声明消息队列
    @Bean
    public Queue orderQueue() {
        // 参数:队列名、持久化、非独占、消费者断开自动删除队列
        return new Queue("order_queue", true, false, true);
    }

    // 3. 绑定交换机与队列,指定路由键
    @Bean
    public Binding bindingOrder() {
        return BindingBuilder.bind(orderQueue()).to(orderExchange()).with("order.create");
    }

    // 4. JSON消息转换器(解决反序列化安全报错)
    @Bean
    public Jackson2JsonMessageConverter messageConverter() {
        Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter();
        // 配置可信实体包白名单,规避高版本AMQP安全限制
        DefaultJackson2JavaTypeMapper typeMapper = new DefaultJackson2JavaTypeMapper();
        typeMapper.setTrustedPackages("com.ruoyi.system.mq.message");
        converter.setJavaTypeMapper(typeMapper);
        return converter;
    }
}

3.3 消息实体 OrderMessage.java

java

package com.ruoyi.system.mq.message;

import java.io.Serializable;

public class OrderMessage implements Serializable {
    private static final long serialVersionUID = 1L;

    private String orderId;       // 订单编号
    private String productName;   // 商品名称

    public String getOrderId() {
        return orderId;
    }

    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    @Override
    public String toString() {
        return "OrderMessage{" +
                "orderId='" + orderId + '\'' +
                ", productName='" + productName + '\'' +
                '}';
    }
}

3.4 生产者 OrderProducer.java

java

package com.ruoyi.system.mq.producer;

import com.ruoyi.system.mq.message.OrderMessage;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class OrderProducer {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 发送订单消息
     * @param message 订单消息实体
     */
    public void sendOrderMessage(OrderMessage message) {
        // 参数:交换机名称、路由键、消息对象
        rabbitTemplate.convertAndSend("order_exchange", "order.create", message);
    }
}

3.5 消费者 OrderConsumer.java

java

运行

package com.ruoyi.system.mq.consumer;

import com.ruoyi.system.mq.message.OrderMessage;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class OrderConsumer {

    // 监听指定队列
    @RabbitListener(queues = "order_queue")
    public void handleOrderMessage(OrderMessage message) {
        System.out.println("【消费者】收到订单消息:" + message);
        // 此处编写业务逻辑:扣库存、发通知、记录日志等
    }
}

3.6 测试控制器 MqTestController.java

java

package com.ruoyi.web.controller.test;

import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.system.mq.message.OrderMessage;
import com.ruoyi.system.mq.producer.OrderProducer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test/mq")
public class MqTestController {

    @Autowired
    private OrderProducer orderProducer;

    @GetMapping("/send")
    @Anonymous // 若依免登录注解
    public String sendMessage() {
        // 封装测试消息
        OrderMessage msg = new OrderMessage();
        msg.setOrderId("ORD202607060001");
        msg.setProductName("MacBook Pro 16寸");
        // 发送消息
        orderProducer.sendOrderMessage(msg);
        return "消息发送成功!查看后端控制台消费日志";
    }
}

四、完整测试使用流程

4.1 前置环境准备

  1. 启动 RabbitMQ 服务

bash

# Windows查看服务
net start | findstr RabbitMQ
# 未启动则执行
net start RabbitMQ
  1. 开启管理后台插件

bash

cd RabbitMQ安装目录/sbin
rabbitmq-plugins enable rabbitmq_management
# 重启服务生效
net stop RabbitMQ
net start RabbitMQ

访问管理后台:http://localhost:15672,账号密码 guest/guest。

4.2 启动若依项目

执行项目根目录ry.bat启动后端,观察日志出现 RabbitMQ 连接成功提示: Connection established to RabbitMQ at localhost:5672

4.3 发送消息两种方式

  1. 浏览器访问:http://localhost:8080/test/mq/send,页面返回发送成功;
  2. curl 命令调用:

base

curl http://localhost:8080/test/mq/send

4.4 验证消费结果

  1. 后端控制台输出日志: 【消费者】收到订单消息:OrderMessage{orderId='ORD202607060001', productName='MacBook Pro 16寸'}
  2. RabbitMQ 后台队列order_queue Ready 消息数变为 0,代表消费完成;
  3. 查看消息原始 JSON 数据(后台 Get Messages):

json

{
  "__TypeId__": "com.ruoyi.system.mq.message.OrderMessage",
  "orderId": "ORD202607060001",
  "productName": "MacBook Pro 16寸"
}

4.5 批量测试命令

Windows CMD 批量发送 10 条消息:

bash

for /l %i in (1,1,10) do curl http://localhost:8080/test/mq/send

五、开发高频报错与解决方案

问题 1:接口 401 认证失败

报错:请求访问:/test/mq/send,认证失败,无法访问系统资源 原因:若依默认所有接口需要登录,测试接口未放行 解决:接口方法添加@Anonymous注解,导入对应包com.ruoyi.common.annotation.Anonymous

问题 2:反序列化 SecurityException 安全异常

报错:Attempt to deserialize unauthorized class xxx 原因:Spring AMQP2.10 + 新增反序列化白名单安全机制 解决:配置 Jackson2JsonMessageConverter 并设置可信包,参考 RabbitMQConfig 代码。

问题 3:消息格式转换异常 MessageConversionException

报错:Cannot convert byte[] to OrderMessage,contentType=application/x-java-serialized-object 原因:队列残留旧 Java 序列化消息,新代码使用 JSON 转换器格式不兼容 解决:队列构造第四个参数设置autoDelete=true,重启项目自动清空旧消息;或后台手动 Purge 队列。

问题 4:RabbitMQ 连接拒绝 Connection refused: connect

原因:RabbitMQ 未启动、yml 端口写成 15672(管理端口) 解决:确认服务运行,spring.rabbitmq.port 固定为 5672。

问题 5:Jackson2JsonMessageConverter 废弃警告

提示:deprecated since version 4.0 解决:无需删除转换器,搭配 DefaultJackson2JavaTypeMapper 配置即可消除警告,官方推荐过渡方案。

六、部署 & 排查检查清单

6.1 启动前自检

  1. RabbitMQ 服务正常运行,管理后台可登录;
  2. application.yml MQ 连接地址、端口、账号无误;
  3. 实体类放入可信包路径,转换器配置完整;
  4. 测试接口添加@Anonymous免登录注解。

6.2 测试成功判定标准

  1. 接口访问返回消息发送成功;
  2. 控制台打印消费者日志;
  3. RabbitMQ 队列无堆积消息;
  4. 无任何异常堆栈报错。

6.3 常见故障快速排查

  1. 消息发送成功无消费日志:查看应用是否有反序列化异常、消费者是否在线;
  2. 消息大量堆积 Ready>0:消费者未启动、业务代码阻塞、抛出异常未处理;
  3. 交换机 / 队列不存在:重启项目,@Bean 配置会自动声明资源。

七、进阶拓展方向

  1. 手动 ACK 确认:关闭 auto 自动确认,手动控制消息重试、死信;
  2. 死信队列 DLQ:消费失败消息转入死信队列,定时重试;
  3. 生产者确认机制:Publisher-Confirm 保障消息可靠投递;
  4. 延迟队列:实现订单超时取消、定时通知;
  5. MQ 集群高可用:镜像队列、负载均衡;
  6. 监控告警:队列积压、消费速率监控。

八、总结

本文完整实现若依框架 RabbitMQ 基础消息收发,覆盖配置、实体、生产者、消费者、测试接口全套代码,同时解决开发中 5 个核心坑点。 消息队列核心价值:

  1. 异步解耦:前端无需等待复杂业务,提升接口响应;
  2. 流量削峰:高并发请求缓冲,避免数据库瞬时压垮;
  3. 可靠异步:订单、通知、日志等非实时业务最佳实践。 整套代码可直接复制到项目运行,适配日常开发、毕业设计、企业项目开发使用。

文档适配版本: RuoYi-Vue 3.9.2 | RabbitMQ 4.3.2 | Spring AMQP 3.1.x

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐