一、什么是RocketMQ
1、什么是MQ
(1)定义
MQ 是一种基于 "生产者 - 消费者" 模型 的异步通信中间件 ,它的核心作用是存储和转发消息 ,让消息的发送方(生产者)和接收方(消费者)解耦、异步、削峰填谷。
可以把 MQ 想象成一个快递驿站:
- 生产者:就是寄快递的人,把包裹(消息)放到驿站,不用等收件人当面签收,放下就走。
- MQ 服务器:就是驿站本身,负责保管包裹,记录包裹的收件人、存放位置。
- 消费者:就是收件人,随时可以去驿站取包裹,也可以让驿站送货上门(主动拉取 / 被动推送)。
(2)MQ 解决的核心问题
在分布式系统中,MQ 是不可或缺的组件,主要解决以下痛点:
- 系统解耦传统同步调用中,A 系统直接调用 B 系统接口,如果 B 系统宕机,A 系统也会受影响。引入 MQ 后,A 系统只需要把消息发送到 MQ,无需关心 B 系统的状态;B 系统从 MQ 消费消息,即使 A 系统宕机,也不影响后续处理。
- 异步通信同步调用会导致请求阻塞,比如用户下单后,需要同步调用库存、支付、物流接口,整个流程耗时较长。引入 MQ 后,下单请求完成后,直接发送消息到 MQ,库存、支付等系统异步消费,用户无需等待所有流程完成,提升响应速度。
- 削峰填谷 在秒杀、促销等场景下,短时间内会有大量请求涌入,直接打到业务系统会导致系统崩溃。MQ 可以缓冲这些请求,让消费者按照自身的处理能力匀速消费,避免系统被峰值流量冲垮。
- 消息分发一条消息可以被多个消费者消费(发布 - 订阅模式),比如订单创建后,库存系统、积分系统、日志系统都需要获取该消息。
(3)MQ 的基本工作模型
Producer → MQ Broker → Consumer
关键特性包括:
-
消息持久化
-
消息顺序控制
-
消费确认(ACK)
-
重试 / 死信
(4)常见的 MQ 产品
市面上主流的 MQ 产品有以下几种,各有特点:
| 产品 | 语言 | 特点 | 适用场景 |
|---|---|---|---|
| ActiveMQ | Java | 老牌 MQ,支持多种协议,文档丰富 | 中小型系统、对性能要求不高的场景 |
| RabbitMQ | Erlang | 基于 AMQP 协议,轻量级,高并发,社区活跃 | 实时性要求高的场景、微服务通信 |
| Kafka | Scala/Java | 高吞吐量、高持久化,适合大数据场景 | 日志收集、大数据分析、流式处理 |
| RocketMQ | Java | 阿里开源,高可靠、低延迟,支持事务消息 | 电商、金融等核心业务系统 |
2、RocketMQ 详解
(1)定义
RocketMQ 是由阿里巴巴 开源的一款分布式消息中间件 ,2016 年捐赠给 Apache 基金会,成为 Apache 顶级项目。它基于 Java 开发,专为高并发、高可靠的分布式系统设计,在阿里内部经过了双 11 等海量流量场景的考验。
(2)RocketMQ 的核心架构
RocketMQ 采用分布式集群架构,核心组件分为 4 个部分,各司其职:
-
NameServer(命名服务)
- 核心作用 :轻量级的注册中心,管理 Broker 的信息,提供路由发现服务。
- 特点 :无状态、集群部署(节点之间不通信),生产者和消费者通过 NameServer 获取 Broker 的地址,实现动态扩容。
- 类比 :相当于快递驿站的总调度中心,记录所有驿站(Broker)的地址和服务范围。
-
Broker(消息服务器)
- 核心作用 :消息的存储和转发核心,负责接收生产者的消息、存储消息、推送给消费者。
- 架构 :Broker 分为 Master 和 Slave ,Master 负责读写,Slave 负责备份,实现高可用。
- 存储机制 :消息存储在本地磁盘,采用顺序写的方式,性能远高于随机写。
- 类比 :相当于具体的快递驿站,负责包裹的接收、存储和派送。
-
Producer(生产者)
- 核心作用 :消息的发送方,负责生产消息并发送到 Broker。
- 发送模式 :支持同步发送 (等待 Broker 确认)、异步发送 (不等待确认,通过回调通知)、单向发送(只发不收,适合日志等场景)。
- 负载均衡:生产者通过 NameServer 获取 Broker 列表后,会采用轮询等策略选择 Broker 发送消息,避免单节点压力过大。
-
Consumer(消费者)
- 核心作用 :消息的接收方,负责从 Broker 拉取或接收消息并处理。
- 消费模式 :
- Push 模式:Broker 主动将消息推送给消费者(实际是 Consumer 长轮询 Broker)。
- Pull 模式:消费者主动向 Broker 拉取消息,灵活性更高。
- 消费组 :多个消费者可以组成一个消费组,共同消费一个 Topic 的消息,实现负载均衡消费;同一个消费组内的消费者,一条消息只会被消费一次。
(3)RocketMQ 的核心概念
- Topic(主题)
- 消息的分类标识,生产者发送消息时需要指定 Topic,消费者订阅 Topic 来消费消息。
- 类比:相当于快递的 "快递类型",比如 "生鲜快递""普通快递",消费者可以只订阅自己关心的类型。
- Tag(标签)
- Topic 的细分,可以在同一个 Topic 下设置多个 Tag,实现更细粒度的消息过滤。
- 例如:一个
order_topic下,可以设置create_order、pay_order、cancel_order三个 Tag,消费者可以只消费pay_order的消息。
- Message Queue(消息队列)
- 每个 Topic 会被划分为多个 Message Queue(队列),分布在不同的 Broker 上。
- 作用:提升并发能力,生产者将消息发送到不同的队列,消费者可以并行消费不同队列的消息。
- Offset(偏移量)
- 每个 Message Queue 中的消息都有一个唯一的 Offset,标记消息的位置。
- 消费者通过记录 Offset,来确认自己已经消费到哪条消息,支持断点续传。
(4)RocketMQ 的核心特性
RocketMQ 之所以能成为电商、金融等核心场景的首选 MQ,是因为它具备以下特性:
- 高可靠
- 支持同步刷盘 (消息写入磁盘后才返回确认)和异步刷盘,支持 Master/Slave 主从复制,即使 Master 宕机,Slave 也能无缝切换。
- 支持消息回溯,可以根据 Offset 重新消费历史消息。
- 高吞吐量
- 采用顺序写磁盘 、零拷贝等技术,单机吞吐量可达几十万 TPS,满足海量消息场景。
- 支持事务消息
- 解决分布式事务问题,比如 "下单扣库存" 场景,通过事务消息保证订单和库存的一致性。
- 延迟消息
- 支持定时投递消息,比如 "订单创建后 30 分钟未支付则自动取消",无需手动轮询。
- 死信队列
- 消费失败的消息会被投递到死信队列,方便后续排查问题,避免消息丢失。
(5)RocketMQ 的适用场景
- 电商交易:订单创建、支付回调、库存更新等场景,通过异步消息提升系统响应速度。
- 金融支付:交易对账、通知推送,通过事务消息保证数据一致性。
- 日志收集:类似 Kafka,收集分布式系统的日志,进行集中分析。
- 秒杀活动:通过削峰填谷,缓冲峰值流量,避免系统崩溃。
- 微服务通信:实现微服务之间的解耦,替代同步 RPC 调用。
(6)RocketMQ 与 Kafka 的对比
很多人会把 RocketMQ 和 Kafka 做对比,两者的核心差异如下:
| 特性 | RocketMQ | Kafka |
|---|---|---|
| 定位 | 分布式消息中间件,兼顾可靠性和实时性 | 分布式日志收集系统,主打高吞吐量 |
| 事务消息 | 支持 | 不支持 |
| 延迟消息 | 原生支持 | 需要通过时间轮实现 |
| 消息回溯 | 支持按 Offset、时间回溯 | 仅支持按 Offset 回溯 |
| 运维友好性 | 提供丰富的运维工具,部署简单 | 依赖 Zookeeper,运维成本较高 |
| 生态 | 与 Spring Cloud 等微服务框架集成友好 | 与大数据生态(Spark、Flink)集成友好 |
二、RocketMQ集群
1、集群设计的核心目标
- 高可用:任意单个节点宕机,不影响整个集群的正常运行。
- 高吞吐量:通过多 Broker 节点分担消息存储和收发压力,提升整体处理能力。
- 数据可靠性:通过主从复制,避免单节点数据丢失。
- 弹性扩容:支持在线添加 / 移除节点,无需停止集群服务。
2、集群的核心组成
RocketMQ 集群由 NameServer 集群 和 Broker 集群 两部分构成,两者相互配合,支撑整个消息链路。
(1)NameServer 集群
NameServer 是 RocketMQ 的轻量级注册中心 ,负责管理 Broker 的路由信息,本身是无状态的(节点之间不通信、不共享数据)。
1)、集群特点
- 去中心化:所有 NameServer 节点地位平等,没有主从之分。
- 无状态设计:每个 NameServer 都完整存储所有 Broker 的路由信息,Producer/Consumer 连接任意一个 NameServer 都能获取全量路由。
- 动态感知 Broker:Broker 会定期向所有 NameServer 发送心跳包(默认 30s),上报自身状态(存活、Topic 配置等);如果 NameServer 超过 120s 没收到 Broker 心跳,就会将其从路由表中移除。
2)、集群部署建议
- 生产环境至少部署 3 个节点,保证容错性(单节点宕机不影响服务)。
- 节点之间无需配置集群关系,只需启动多个 NameServer 实例即可。
- Producer/Consumer 配置多个 NameServer 地址(用
;分隔),实现故障自动切换。
3)、作用
- 管理 Broker 的注册与发现,Producer/Consumer 通过 NameServer 获取 Broker 的地址。
- 存储 Topic 与 Broker 的映射关系(哪个 Topic 分布在哪些 Broker 的哪些队列上)。
(2)Broker 集群
Broker 是 RocketMQ 的核心业务节点 ,负责消息的接收、存储、投递,是集群的 "数据载体"。Broker 集群的部署模式决定了集群的可靠性和吞吐量,主流部署模式有 主从模式 和 Dledger 集群模式。
1)、Broker 节点角色
Broker 分为 Master 和 Slave 两种角色:
- Master 节点 :负责处理读写请求,Producer 只能将消息发送到 Master。
- Slave 节点 :负责同步 Master 的数据,仅处理读请求(Consumer 可以从 Slave 拉取消息),实现读写分离。
2)、主流部署模式
模式 1: 同步双写 / 异步复制主从模式(传统模式)
这是早期 RocketMQ 的主从部署方式,一个 Master 对应一个或多个 Slave,数据复制方式分为两种:
-
同步双写(SYNC_MASTER)
- 原理:Producer 发送消息到 Master 后,Master 会将消息同步写入 Slave,只有 Slave 写入成功后,才向 Producer 返回确认。
- 优点:数据零丢失,可靠性最高。
- 缺点:同步等待会增加消息发送延迟,降低吞吐量。
- 适用场景:金融、交易等对数据可靠性要求极高的场景。
-
异步复制(ASYNC_MASTER)
- 原理:Producer 发送消息到 Master 后,Master 写入本地磁盘就向 Producer 返回确认,异步将数据复制到 Slave。
- 优点:延迟低、吞吐量高。
- 缺点:Master 宕机可能导致少量未复制到 Slave 的数据丢失。
- 适用场景:电商、日志等对延迟敏感,对数据丢失容忍度较高的场景。
-
传统主从模式的局限性
- Master 宕机后,需要手动切换 Slave 为新的 Master(需修改配置 + 重启),无法自动故障转移。
- 不支持自动扩容,添加节点需要手动配置。
模式 2: Dledger 集群模式(推荐生产使用)
Dledger 是 RocketMQ 基于 Raft 协议 实现的分布式共识组件,解决了传统主从模式无法自动故障转移 的问题,实现了 自动选主、数据一致性。
- 集群组成 :一个 Dledger 集群由 3 个或 5 个 Broker 节点组成(奇数节点,满足 Raft 协议的投票机制),节点角色会动态变化(Leader/Follower)。
- 核心原理
- 集群启动后,通过 Raft 协议选举出一个 Leader 节点 (相当于主从模式的 Master),其余为 Follower 节点(相当于 Slave)。
- Producer 只能向 Leader 发送消息,Leader 会将消息同步到多数 Follower 节点(超过半数)后,才返回确认。
- 如果 Leader 宕机,剩余节点会重新选举新的 Leader,全程自动完成,无需人工干预。
- 优点
- 自动故障转移:Leader 宕机后秒级切换,不中断业务。
- 数据强一致性:基于 Raft 协议,保证多数节点写入成功才确认,避免数据丢失。
- 运维简单:无需手动配置主从关系,支持在线扩容。
- 适用场景:生产环境首选,尤其是对高可用要求高的核心业务。
3、集群的负载均衡机制
RocketMQ 集群的高吞吐量,很大程度上依赖于多层负载均衡设计,分为以下两个层面:
(1)Producer 端负载均衡
Producer 发送消息时,会根据以下策略选择具体的 Broker 和 Message Queue:
- Producer 从 NameServer 获取 Topic 对应的 Broker 列表。
- 通过 轮询 / 随机 策略选择一个 Broker 节点(默认轮询)。
- 在选中的 Broker 中,再通过轮询策略选择一个 Message Queue 发送消息。
- 作用:将消息均匀分布到多个 Broker 和多个队列,避免单节点 / 单队列压力过大。
(2)Consumer 端负载均衡
Consumer 消费消息时,消费组(Consumer Group)内的多个 Consumer 实例会分摊消费 同一个 Topic 的消息,核心策略是 队列分配:
- 同一个消费组内的 Consumer 会通过心跳向 Broker 上报自己的状态。
- Broker 或 Consumer 协调者(默认是 Broker)会将 Topic 的所有 Message Queue 均匀分配 给消费组内的 Consumer。
- 例如:Topic 有 8 个队列,消费组有 2 个 Consumer,则每个 Consumer 分配 4 个队列。
- 注意:队列数必须大于等于 Consumer 实例数,否则部分 Consumer 会空闲。
- 一个 Message Queue 只会被消费组内的 一个 Consumer 消费,保证消息不重复消费。
- 常见的队列分配策略:平均分配、一致性哈希、按机房分配等,可通过配置自定义。
4、集群部署的核心注意事项
- NameServer 集群:至少 3 节点,无状态部署,客户端配置多个 NameServer 地址。
- Broker 集群 :生产环境优先选择 Dledger 模式,节点数为 3/5 个奇数;传统主从模式适合对自动切换无要求的场景。
- 存储配置 :Broker 的消息存储目录建议挂载 独立磁盘,采用顺序写,提升 IO 性能;同时配置合理的消息过期时间,避免磁盘占满。
- 网络规划 :NameServer 和 Broker 建议部署在同一个内网,减少网络延迟;Producer/Consumer 与集群的网络尽量低延迟。
- 监控运维:部署 RocketMQ Dashboard 监控集群状态(Broker 存活、消息堆积、消费进度等),及时发现异常。
5、集群与单机的核心区别
| 特性 | 单机部署 | 集群部署 |
|---|---|---|
| 高可用 | 单节点宕机,服务完全不可用 | 部分节点宕机,服务正常运行 |
| 吞吐量 | 受限于单节点性能 | 随节点数量线性提升 |
| 数据可靠性 | 单节点故障,数据可能丢失 | 主从复制 / Dledger 保证数据不丢失 |
| 适用场景 | 开发测试、小型应用 | 生产环境、高并发核心业务 |
三、安装本地服务
1、安装java必须环境JDK
推荐使用jdk8或jdk11,我使用的是jdk8
XML
sudo apt update
先使用update更新一下:
安装jdk8
XML
sudo apt install -y openjdk-8-jdk
安装成功

可以使用下面命令检测是否成功安装
java -version
出现下面结果表示安装成功

如何需要和win系统上一样配置环境变量
nano ~/.bashrc
添加如下配置,最后一个配置是为了告诉RocketMQ,Namesrv服务启动在什么地方了
# JAVA ENV
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export PATH=$PATH:$JAVA_HOME/bin
export NAMESRV_ADDR='localhost:9876'

输入下面命令使刚刚的配置生效
source ~/.bashrc
验证是否生效
echo $JAVA_HOME

2、下载RocketMQ
切换到安装目录
cd /opt

下载RocketMQ
sudo wget https://downloads.apache.org/rocketmq/5.1.4/rocketmq-all-5.1.4-bin-release.zip
下载完成

解压
sudo apt install -y unzip
unzip rocketmq-all-5.1.4-bin-release.zip
解压成功

将解压的文件移入一个专门的文件夹方便管理,需要先提前自己创建好文件夹哦
sudo mv rocketmq-all-5.1.4-bin-release rocketmq

修改JVM内存配置
修改 NameServer 启动内存
sudo nano bin/runserver.sh
修改图片中的参数即可

修改 Broker 启动内存
sudo nano bin/runbroker.sh

3、启动服务
启动 NameServer
XML
cd /opt/rocketmq
nohup sh bin/mqnamesrv &
还可以用jps命令验证,记住一定要切换到对于目录再启动

启动 Broker(单机模式)
XML
nohup sh bin/mqbroker &
可以用jps命令验证

关闭服务的命令如下
java
sh bin/mqshutdown broker
sh bin/mqshutdown namesrv
4、验证
发送消息
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Producer

接收消息
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer
这个需要我们自己退出

四、搭建Java客户端
1、首先创建一个maven项目

2、添加对应的依赖
XML
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>5.1.4</version>
</dependency>

3、编写生产者代码(ip地址是启动服务的IP地址)
java
public class Producer {
public static void main(String[] args) throws Exception {
// 1. 创建 Producer,指定 ProducerGroup
DefaultMQProducer producer =
new DefaultMQProducer("test_producer_group");
// 2. 设置 NameServer 地址(必须)
producer.setNamesrvAddr("192.168.47.138:9876");
// 3. 启动 Producer
producer.start();
// 4. 构造消息
Message msg = new Message(
"TestTopic",
"TagA",
"Hello RocketMQ".getBytes()
);
// 5. 发送消息
producer.send(msg);
System.out.println("Message sent successfully");
// 6. 关闭
producer.shutdown();
}
}
4、编写消费者代码
java
public class Consumer {
public static void main(String[] args) throws Exception {
// 1. 创建 Consumer
DefaultMQPushConsumer consumer =
new DefaultMQPushConsumer("test_consumer_group");
// 2. 设置 NameServer
consumer.setNamesrvAddr("192.068.47.138:9876");
// 3. 订阅 Topic
consumer.subscribe("TestTopic", "*");
// 4. 注册监听器
consumer.registerMessageListener(
(MessageListenerConcurrently) (msgs, context) -> {
msgs.forEach(msg ->
System.out.println(
new String(msg.getBody())
)
);
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
});
// 5. 启动
consumer.start();
System.out.println("Consumer started");
}
}
5、验证
先启动 NameServer和 Broker

启动 Producer

启动 Consumer

看到上述结果表示搭建成功。
五、可视化管理服务
在单机部署完成的前提下,可以直接从git上获取源码
java
git clone https://github.com/apache/rocketmq-dashboard.git
cd rocketmq-dashboard

然后需要配置 NameServer 地址
java
nano src/main/resources/application.yml
端口号默认的8082,我就没有修改


下载的maven使用的是jdk17,所以还需要下载一个jdk17
java
# 更新软件源
sudo apt update && sudo apt upgrade -y
# 安装OpenJDK 17(包含JDK和JRE)
sudo apt install -y openjdk-17-jdk openjdk-17-jre
配置jdk17 的环境变量
java
# 编辑/etc/profile文件(对所有用户生效,需sudo)
sudo nano /etc/profile
在文件末尾添加如下内容(先通过update-alternatives --config java找到 JDK 17 的安装路径,替换下方/usr/lib/jvm/java-17-openjdk-amd64):
java
# 配置JDK 17环境变量
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:${PATH}
使环境变量生效:
java
source /etc/profile
重新执行java -version和javac -version,确认均显示 JDK 17 版本;同时执行echo $JAVA_HOME,应输出配置的 JDK 17 路径。
生成jar包(跳过不必要检查)
java
mvn clean package -Dmaven.test.skip=true -Dcheckstyle.skip=true

使用nohup命令实现后台运行,并将日志输出到文件:
java
nohup java -jar target/rocketmq-dashboard-2.1.1-SNAPSHOT.jar > dashboard.log 2>&1 &

进入浏览器,输入你启动服务的ip地址以及服务的端口,默认是8080,我的是默认8082我没有修改。
