一、基础概念
1、什么是RabbitMQ ?
RabbitMQ 是一款开源、轻量级、可靠的消息中间件(Message Queue) ,采用 Erlang 语言开发,基于 AMQP 0-9-1 高级消息队列协议,跨平台、多语言客户端支持(Java/Python/Go/PHP 等)。
核心作用:解耦、削峰、异步、最终一致性,解决分布式系统通信问题。
2、核心术语(AMQP 模型)
- 生产者 Producer 发送消息的应用程序,不直接发给队列,先发给交换机。
- 消费者 Consumer 监听队列、接收并处理消息的应用。
- 消息 Message 传输数据,包含两部分:
- Header:属性(路由 key、持久化、优先级、过期时间等)
- Body:业务数据(JSON / 字符串 / 二进制)
- 虚拟主机 Virtual Host(vhost) Rabbit 的隔离命名空间,相当于小型独立 Rabbit 服务。 不同 vhost 交换机、队列互不干扰,用于多环境、多项目隔离,默认
/。 - 交换机 Exchange 接收生产者消息,根据规则路由到队列,队列不直接绑定生产者。
- 绑定 Binding 交换机 ↔ 队列之间的关联关系,绑定需要
RoutingKey。 - 队列 Queue 存储消息的容器,先进先出 FIFO;消息最终存在队列等待消费者消费。
- Broker RabbitMQ 服务实例整体统称,包含交换机、队列、vhost 全部组件。
二、交换机 Exchange 四大类型(核心重点)
交换机决定消息分发策略,四种内置类型:
1. Direct 直连交换机(精准匹配)
- 规则:消息
routingKey= 绑定bindingKey,精准匹配才投递队列 - 使用场景:点对点、单任务分发、精准定向推送
- 示例:订单支付成功只通知订单服务,路由 key
order.pay
2. Fanout 扇形交换机(广播)
- 规则:忽略 routingKey,所有绑定该交换机的队列全部收到同一条消息
- 使用场景:广播通知、日志同步、多服务同时更新缓存
- 示例:商品上新,推送给搜索服务、推荐服务、库存服务
3. Topic 主题交换机(模糊匹配,最常用)
- 规则:支持通配符模糊匹配 routingKey
*:匹配一个单词#:匹配零个或多个单词 单词用.分隔,例:user.create、order.pay.success
- 使用场景:日志分级、多维度业务消息、多订阅规则
- 示例:
log.*接收所有一级日志(log.info、log.error)log.#接收所有日志
4. Headers 头交换机(极少用)
不依赖 routingKey,通过消息 header 键值对匹配,性能差,业务几乎不用。
补充:默认交换机
Rabbit 自带匿名直连交换机,名称为空字符串。 特点:所有队列自动与它绑定,bindingKey = 队列名。 生产者直接发 routingKey=队列名,即可直达队列,适合简单场景。
三、消息可靠机制(生产 + 存储 + 消费三层保障)
1. 生产者可靠性:确保消息不丢失
(1)事务机制(不推荐,性能差)
channel.txSelect() 开启事务,发送后 txCommit;失败 txRollback。 缺点:同步阻塞,吞吐量下降几十倍,生产环境弃用。
(2)Publisher Confirms 发布确认(主流方案)
异步确认模式:
- 通道开启
confirmSelect() - 生产者发送消息,Rabbit 处理完成后返回 ack/nack
- ack:消息已正常存入交换机 / 队列
- nack:消息丢失,生产者重发 支持批量确认、异步回调,性能远高于事务。
(3)Return 退回消息
消息无法路由到任何队列时触发回调(无匹配队列),生产者可捕获重发。
2. 服务端可靠性:消息持久化
两个持久化配置必须同时开启才不会丢消息:
- 队列持久化 :创建队列参数
durable=true - 消息持久化 :发送消息时
deliveryMode=2(持久化) 重启 Rabbit 后,持久化消息不会丢失;非持久化内存消息重启清空。
注意:仅持久化会丢数据场景:磁盘满、机器宕机未刷盘,需配合镜像队列。
3. 消费者可靠性:手动 ACK 防止消息丢失
两种确认模式:
- 自动 ACK(autoAck=true) Rabbit 消息推送给消费者立刻标记删除;若消费者中途崩溃,消息直接丢失,业务禁止使用。
- 手动 ACK(autoAck=false,推荐) 消费者业务处理完成后手动调用
basicAck;- 正常消费:
basicAck(deliveryTag, multiple=false)确认删除 - 处理失败:
basicNack(deliveryTag, multiple=false, requeue=true)重新放回队列 requeue=false:丢弃消息 / 转发死信队列
- 正常消费:
四、死信队列 DLX(Dead Letter Exchange)
1. 消息成为死信的 4 种情况
- 消费者 nack 且 requeue=false(拒绝不重入)
- 消息过期(TTL 超时未消费)
- 队列达到最大长度,溢出消息
- 消息被 basic.reject 拒绝
2. 使用流程
- 创建普通业务队列,绑定 DLX 死信交换机 + 死信路由 key
- 创建死信队列,绑定死信交换机
- 死信自动转发到死信队列,单独监听处理异常消息(重试、告警、记录)
3. 消息 TTL 过期
两种设置方式:
- 队列级别:队列所有消息统一过期时间
- 消息级别:单条消息单独过期时间(优先级更高) 结合死信队列可实现延迟队列(简易延迟方案)。
五、高级特性
1. 延迟消息(两种方案)
- TTL+DLX 死信延迟(低成本,精度差) 队列设置过期时间,到期转发死信,适合分钟级延迟,毫秒误差大。
- rabbitmq-delayed-message-exchange 插件(推荐) 官方延时插件,新增
x-delayed-message交换机类型,发送时指定延迟毫秒,精准可控,生产常用。
2. 消息限流 Qos(消费者预取)
channel.basicQos(prefetchCount) 控制消费者未确认消息最大数量,避免一次性推送几万条压垮消费者。 例:Qos=10,消费者最多持有 10 条未 ack 消息,处理完一条才会推送下一条。
3. 队列模式:普通队列 / 镜像队列 / 集群队列
- 普通队列:仅存在当前节点,节点宕机队列消息全部丢失
- 镜像队列(高可用) 集群环境,队列同步复制到多个节点,主节点故障自动切换镜像节点,保证消息不丢失。
- 队列持久化 + 镜像队列 = 生产高可用标配
4. 消息优先级
创建队列时设置 x-max-priority=10(0~10 级),高优先级消息优先被消费,适合紧急订单、告警消息。
5. 独占队列、临时队列
临时队列:消费者断开自动删除,配合 Fanout 做临时订阅; 独占队列:仅当前消费者可监听,适用于独占任务。
6. 幂等性(必做!)
MQ 不保证消息只投递一次,存在重复消费,业务必须实现幂等: 方案:
- 每条消息携带唯一 msgId,消费前查数据库 / Redis 是否已处理
- 数据库唯一约束,重复插入直接报错跳过
- Redis 记录已消费消息 ID,设置过期时间
六、集群架构
1. 普通集群
多台 Rabbit 节点共享元数据(交换机、队列配置),消息只存在创建队列的节点,节点宕机消息丢失,仅做配置共享,无高可用。
2. 镜像集群(生产高可用)
队列数据同步到集群多个节点,主节点故障,镜像节点升级为主,消息不丢失。 配置策略指定哪些队列开启镜像。
3. 联邦集群 / 跨地域集群
多机房、异地 Rabbit 同步消息,解决跨区域消息互通,不依赖统一集群。
七、使用场景
- 系统解耦 下单后不用同步调用库存、支付、短信;发消息到 MQ,各服务异步消费,互不阻塞。
- 流量削峰填谷 秒杀大量请求打入队列,消费者匀速处理,避免数据库瞬间压垮。
- 异步处理 短信、邮件、日志、文件导出、大数据统计,不阻塞主流程。
- 最终一致性(分布式事务) 可靠消息事务:本地消息表 + Rabbit 可靠投递,实现跨服务数据一致。
- 定时任务 / 延迟任务 订单 30 分钟未支付自动取消、超时退款。
- 广播通知 配置更新、缓存刷新、多服务同步数据。
八、优缺点
优点
- 可靠性高:持久化、确认机制、镜像集群,消息不易丢失
- 灵活路由:四种交换机适配各类分发场景
- 轻量稳定:Erlang 高并发、低内存占用,百万级消息无压力
- 多语言、成熟生态,监控完善(Management 管理面板)
- 功能丰富:死信、延迟、限流、优先级、vhost 隔离
缺点
- 不适合海量超大数据流(Kafka 吞吐量更高)
- 分布式事务实现复杂,无原生事务
- 延迟插件精度有限,超大规模延迟任务成本高
- 集群运维有一定学习成本
九、与 Kafka 核心区别(面试高频)
| 特性 | RabbitMQ | Kafka |
|---|---|---|
| 定位 | 可靠业务消息,复杂路由 | 高吞吐日志、数据流 |
| 吞吐量 | 万级 | 十万 / 百万级 |
| 消息模型 | 消费后删除 | 日志持久化,可重复消费 |
| 路由能力 | 交换机灵活路由 | 仅分区 + topic,路由简单 |
| 可靠性 | 强可靠,适合金融订单 | 高吞吐优先,丢失容忍度更高 |
| 使用场景 | 订单、支付、短信、延迟任务 | 日志收集、大数据流、实时计算 |
十、常见问题与踩坑
- 消息丢失三大场景
- 生产者未开启 confirm,网络断连消息丢失
- 队列 / 消息未持久化,服务重启清空
- 自动 ack,消费者崩溃消息未处理完直接删除
- 消息堆积 消费速度 < 生产速度,解决方案:提高消费者数量、批量消费、限流生产、拆分队列
- 死信队列堆积 异常消息持续产生,需定时清理死信、告警通知人工处理
- 重复消费 网络超时导致生产者重发,必须业务幂等
- 脑裂问题 集群网络分区,镜像队列出现双主,配置磁盘节点、监控告警规避
十一、简单工作流程总结
- 生产者连接 Broker,创建交换机,发送消息携带 routingKey
- 交换机根据类型 + routingKey 匹配绑定关系,投递消息到对应队列
- 消息存入队列,持久化落地磁盘
- 消费者监听队列,手动 ACK 处理业务
- 处理失败消息转入死信队列,异常单独处理
- 集群镜像保证节点宕机消息不丢失
十二、Mac m1 PRO 安装 RabbitMQ 的完整步骤
1. 确认安装 Homebrew
M1 芯片 brew 安装路径为 /opt/homebrew,没有先执行安装脚本:
bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
安装结束后终端会输出两行环境变量命令,复制执行,配置 zsh。
验证 brew:
bash
brew -v
2. 一键安装 RabbitMQ(自动装 Erlang)
bash
brew install rabbitmq
3. 配置环境变量(M1 必配,否则命令找不到)
M1 默认 shell 是 zsh,编辑配置文件:
bash
nano ~/.zshrc
文件末尾粘贴:
bash
# RabbitMQ M1 Pro
export PATH=$PATH:/opt/homebrew/opt/rabbitmq/sbin
保存退出:control+O 回车,control+X
刷新配置生效:
bash
source ~/.zshrc
验证命令是否可用:
bash
rabbitmq-server --version
4. 启动 / 停止服务
方案 A:开机自启(推荐开发用)
bash
# 启动后台服务
brew services start rabbitmq
# 停止
brew services stop rabbitmq
# 重启
brew services restart rabbitmq
# 查看运行状态
brew services list
方案 B:临时前台运行(关闭终端即停止)
bash
rabbitmq-server
5. 开启 Web 管理面板
bash
rabbitmq-plugins enable rabbitmq_management
- AMQP 连接端口:5672
- 管理后台端口:15672

默认账号(仅本地localhost可用)
- 用户名:
guest - 密码:
guest

6、创建管理员账号(禁止使用默认 guest)
guest 仅允许本地访问,外网 / 项目连接会报错,新建管理员:
bash
# 创建用户 admin 密码 12345678
rabbitmqctl add_user admin 12345678
# 设置超级管理员权限
rabbitmqctl set_user_tags admin administrator
# 赋予全部虚拟主机权限
rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
# 可选:删除默认guest用户
rabbitmqctl delete_user guest
网页登录账号:admin / 12345678
7. 高频常用命令
bash
# 查看服务状态
rabbitmqctl status
# 查看所有用户
rabbitmqctl list_users
# 查看队列消息数量
rabbitmqctl list_queues name messages
# 查看交换机
rabbitmqctl list_exchanges

十三、Java SpringBoot 整合 RabbitMQ 的完整可运行代码
环境说明
- SpringBoot 2.7.x/ 3.2.x 通用(区分简单注解)
- RabbitMQ 本地安装 / Docker 启动均可
- 实现:简单队列、工作队列、发布订阅、路由、主题 5 种模式完整代码
一、创建项目(两种方式)
方式 1:IDEA 新建 SpringBoot 项目
- File -> New -> Project -> Spring Initializr
- 填写坐标:
- Group:com.mq
- Artifact:rabbit-demo
- Java 版本 8/17
- 勾选依赖:
- Spring for RabbitMQ(spring-boot-starter-amqp)
- Spring Web(可选,方便接口测试)


方式 2:Maven 手动引入依赖 pom.xml
XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.1.0</version>
<relativePath/>
</parent>
<groupId>com.zhbe</groupId>
<artifactId>RabbitMQDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>RabbitMQDemo</name>
<description>RabbitMQDemo</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<!-- RabbitMQ核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!-- 标准web,内置Tomcat + Jackson(解决JSON转换器爆红) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- lombok简化实体 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 统一测试依赖,包含web、amqp测试能力 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
二、application.yml 配置文件
删除默认的 application.properties 文件,然后创建 application.yml 文件
bash
spring:
rabbitmq:
# rabbitmq 服务地址
host: 127.0.0.1
port: 5672
username: admin
password: 12345678
virtual-host: /
# 消息手动确认(推荐生产使用)
listener:
simple:
acknowledge-mode: manual # manual手动 / auto自动
prefetch: 1 # 每次只分发1条消息,公平分发
# 生产者确认
publisher-confirm-type: correlated
publisher-returns: true
三、完整项目目录结构
包名统一:com.zhbe.rabbitmqdemo ,分层清晰,企业标准规范,所有代码对应放置位置标注清楚
bash
rabbit-demo
├── pom.xml
└── src
└── main
├── java
│ └── com
│ └── zhbe
│ └── rabbitmqdemo # 根启动包
│ ├── RabbitDemoApplication.java # 启动类
│ ├── config # 配置层:交换机、队列、RabbitTemplate配置
│ │ └── RabbitConfig.java
│ ├── controller # 测试接口控制器
│ │ └── MqTestController.java
│ ├── consumer # 消费者监听类
│ │ └── RabbitConsumer.java
│ ├── producer # 生产者发送工具类
│ │ └── RabbitProducer.java
│ └── entity # 消息实体对象
│ └── Message.java
└── resources
└── application.yml # RabbitMQ配置文件
四、通用消息实体 Message.java
java
package com.zhbe.rabbitmqdemo.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @program: RabbitMQDemo
* @author: 郭宝
* @create: 2026-06-30 14:24
* @description:
**/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Message {
private Long id;
private String content;
private Long time;
}