- 消息队列
- 后端
- 微服务
- 流处理
【免费下载链接】rocketmq
Apache RocketMQ is a cloud native messaging and streaming platform, making it simple to build event-driven applications.
导读
本文基于 Apache RocketMQ 官方 DLedger 快速部署文档,完整讲解如何通过 DLedger 存储模式构建具备**自动故障切换(Auto Failover)**能力的 RocketMQ 高可用集群。你将掌握从源码构建、fast-try.sh一键启动、mqadmin clusterList状态验证,到手动杀掉 Leader 触发 Raft 重新选主的完整实操链路,并结合当前仓库源码理解enableDLegerCommitLog等核心配置的底层作用。
1. DLedger 模式是什么
RocketMQ-on-DLedger 是一个同名 Broker 组(broker group):同一组内至少需要 3 个节点,节点间通过 Raft 算法自动选举出一个 Leader,其余节点作为 Follower,Leader 与 Follower 之间复制数据,从而保证系统高可用。
该模式具备两个关键特性:
- 自动故障切换:Leader 宕机后,剩余节点自动重新选主,无需人工干预;
- 数据一致性:消息通过 Raft 日志复制,多数派(quorum)确认后才算写入成功,Leader 切换后数据依然保持一致。
此外,一个集群可以横向部署任意多个 RocketMQ-on-DLedger Group 对外提供服务。关于 DLedger 集群的完整新集群部署与旧集群升级方案,见仓库文档 Deployment Guide,本文聚焦“快速试用 + 故障切换验证”这条最短路径。
2. 从源码构建
构建分为两步:先构建 DLedger,再构建 RocketMQ。
2.1 构建 DLedger
$ git clone <openmessaging/dledger 仓库地址> $ cd dledger $ mvn clean install -DskipTests2.2 构建 RocketMQ
$ git clone <apache/rocketmq 仓库地址> $ cd rocketmq $ mvn -Prelease-all -DskipTests clean install -U说明:早期版本的官方文档会执行
git checkout -b store_with_dledger origin/store_with_dledger切换到独立分支。如今 DLedger 已合入 RocketMQ 主代码:当前仓库中已有 store/dledger 实现、conf/dledger 示例配置 与 dledger/fast-try.sh 启动脚本,直接构建主分支即可使用。
构建完成后,产物位于distribution/target/rocketmq-{rocketmq-version}/目录,其中{rocketmq-version}替换为实际版本号(例如5.0.0-SNAPSHOT)。
3. 一键快速部署
构建成功后进入发布包目录,执行内置脚本即可拉起一套完整的 1 Nameserver + 3 Broker(DLedger 三节点组)测试集群:
# {rocketmq-version} 替换为 rocketmq 实际版本,例如 5.0.0-SNAPSHOT $ cd distribution/target/rocketmq-{rocketmq-version}/rocketmq-{rocketmq-version} $ sh bin/dledger/fast-try.sh start查看仓库中的 fast-try.sh 源码,可以看到start动作实际依次做了三件事:
- 启动 Nameserver(
bin/mqnamesrv,堆内存 512m); - 依次以
bin/mqbroker -c ./conf/dledger/broker-n0.conf、broker-n1.conf、broker-n2.conf启动 3 个 Broker(堆内存 1g); - 3 个 Broker 使用同一个
brokerName=RaftNode00、同一组dLegerPeers,构成一个三节点 Raft 组。
快速部署使用的默认配置位于发布包的conf/dledger目录,默认存储路径为/tmp/rmqstore。
3.1 验证集群状态
启动成功后,用 mqadmin 运维命令检查集群状态:
$ sh bin/mqadmin clusterList -n 127.0.0.1:9876正常输出中会列出集群内所有 Broker 及其节点信息。BID(Broker ID)为 0 的节点表示 Master(Leader),其余 BID 非 0 的节点为 Follower(从节点)。与普通主从模式不同,这里的 Leader 是 Raft 组内动态选举产生的,并非配置指定的固定 Master。
4. 核心配置详解
conf/dledger下提供三份示例配置broker-n0.conf、broker-n1.conf、broker-n2.conf,分别对应 Raft 组内的三个节点。以 broker-n0.conf 为例:
brokerClusterName = RaftCluster brokerName=RaftNode00 listenPort=30911 namesrvAddr=127.0.0.1:9876 storePathRootDir=/tmp/rmqstore/node00 storePathCommitLog=/tmp/rmqstore/node00/commitlog enableDLegerCommitLog=true dLegerGroup=RaftNode00 dLegerPeers=n0-127.0.0.1:40911;n1-127.0.0.1:40912;n2-127.0.0.1:40913 ## must be unique dLegerSelfId=n0 sendMessageThreadPoolNums=16其余两份配置与 n0 的差异仅在节点专属字段:listenPort(n1 为 30921、n2 为 30931)、storePathRootDir/storePathCommitLog(/tmp/rmqstore/node01、/tmp/rmqstore/node02)以及dLegerSelfId(n1、n2)。
4.1 关键配置项
| 配置项 | 含义 | 示例/取值 |
|---|---|---|
| enableDLegerCommitLog | 是否启用 DLedger 存储模式 | true |
| dLegerGroup | DLedger Raft 组名,建议与 brokerName 保持一致 | RaftNode00 |
| dLegerPeers | DLedger 组内节点端口信息,同一组内各节点该配置必须完全一致 | n0-127.0.0.1:40911;n1-127.0.0.1:40912;n2-127.0.0.1:40913 |
| dLegerSelfId | 当前节点 ID,必须属于 dLegerPeers 中的一员,同一组内各节点必须唯一 | n0 |
| sendMessageThreadPoolNums | 发送消息线程数,建议与 CPU 核数一致 | 16 |
注意:示例中
listenPort(30911/30921/30931)是 Broker 对外服务端口,dLegerPeers中的 40911/40912/40913 是 DLedger Raft 组内部通信端口,两者互不相同、不可混用。
4.2 配置项的源码依据
上述 DLedger 相关字段定义在存储层的 MessageStoreConfig.java:
private boolean enableDLegerCommitLog = false; // 默认关闭,开启后走 DLedger 存储 private String dLegerGroup; private String dLegerPeers; private String dLegerSelfId;当enableDLegerCommitLog=true时,Broker 的 CommitLog 会替换为 DLedgerCommitLog 实现。其构造函数把配置文件中的字段映射为 DLedger 配置(DLedgerCommitLog.java#L89-L105):
dLedgerConfig.setSelfId(messageStoreConfig.getdLegerSelfId()); dLedgerConfig.setGroup(messageStoreConfig.getdLegerGroup()); dLedgerConfig.setPeers(messageStoreConfig.getdLegerPeers()); dLedgerConfig.setStoreBaseDir(messageStoreConfig.getStorePathRootDir());另外需要注意,BrokerStartup.java#L216 中明确校验:enableControllerMode与enableDLegerCommitLog不能同时为 true,二者是互斥的两种高可用选主方案,启动前需确认配置不冲突。
5. 故障切换(Failover)验证
快速部署成功后,就可以验证本文的核心能力——自动故障切换:
- 确认当前 Leader:执行
clusterList,找到 BID 为 0 的节点; - 杀掉 Leader 进程:以上述三节点配置为例,若 Leader 是绑定端口 30931 的 n2 节点,直接
kill该 Broker 的 Java 进程; - 等待约 10 秒:Raft 选举超时后,组内剩余节点会自动发起新一轮选举;
- 再次执行
clusterList确认状态:Leader 已切换到其他存活节点(如 n0 或 n1),且从节点完成数据补齐。
整个切换过程对生产者和消费者透明,无需重启任何进程、无需人工指定新的 Master。这正是 DLedger 模式相对传统主从复制(需要人工切换或依赖其他组件)的核心优势。
从源码层面看,Leader 切换后之所以能继续正常收发消息,是因为 Broker 启动时注册了角色变更监听器:BrokerController.java#L880-L883 将DLedgerRoleChangeHandler挂到 DLedger 选主器上:
DLedgerRoleChangeHandler roleChangeHandler = new DLedgerRoleChangeHandler(this, defaultMessageStore); ((DLedgerCommitLog) defaultMessageStore.getCommitLog()) .getdLedgerServer().getDLedgerLeaderElector().addRoleChangeHandler(roleChangeHandler);节点角色发生变化(Follower 晋升 Leader / Leader 降级 Follower)时,Broker 会随之调整读写能力与内部状态,从而保证切换后消息写入和消费不被中断。
6. 停止集群
快速试用完毕后,一条命令即可优雅关闭整套集群(先停 3 个 Broker,再停 Nameserver):
$ sh bin/dledger/fast-try.sh stop从脚本实现看,stop会先向BrokerStartup相关进程发送 TERM 信号并等待其退出,最多重试 5 轮,必要时以 KILL 兜底,最后再停止NamesrvStartup进程。
7. 从快速试用走向生产部署
快速部署只是把 3 个 Broker 放在同一台机器上用于验证功能。生产环境请参考仓库配套文档 Deployment Guide,其要点包括:
- 新集群部署:每组至少 3 台机器,参照
conf/dledger示例分别编写 3 份配置(重点保证dLegerPeers一致、dLegerSelfId唯一),再用nohup sh bin/mqbroker -c conf/dledger/xxx-n0.conf &方式逐一后台启动; - 旧集群升级:先停止旧 Broker(或执行
bin/mqshutdown broker),由于 Raft 只对新增消息做复制,要求节点间旧 Commitlog 必须一致(建议用md5sum校验最近至少 2 个 Commitlog 文件,不一致则通过复制补齐),再拷贝到 3 台新机器并修改配置后重启; - 规模下限:虽然 2 节点也能组成 RocketMQ-on-DLedger Group,但缺少故障切换能力——只有至少 3 个节点才能容忍 1 个节点宕机。
结语
本文走通了 RocketMQ DLedger 模式的完整快速试用链路:源码构建 →fast-try.sh start一键启动 →clusterList验证 BID=0 的 Leader → 手动 kill Leader 观察约 10 秒内的自动重新选主 →fast-try.sh stop收尾。结合 MessageStoreConfig.java、DLedgerCommitLog.java 与 BrokerController.java 的源码,可以确认:Raft 选主、数据多数派复制与角色切换回调共同构成了这套高可用机制的底层支撑。生产落地时,再按 Deployment Guide 完成多机部署与旧集群平滑升级即可。
- 消息队列
- 后端
- 微服务
- 流处理
【免费下载链接】rocketmq
Apache RocketMQ is a cloud native messaging and streaming platform, making it simple to build event-driven applications.
相关推荐
Apache RocketMQ DLedger 集群部署与自动容灾切换实践指南
Apache RocketMQ DLedger 集群部署与自动容灾切换实践指南 本指南围绕 RocketMQ on DLedger Group 的完整部署流程展
消息队列后端微服务流处理dotnet-releaser与GitHub Actions完美集成:自动化发布到NuGet和GitHub的终极指南
dotnet releaser与GitHub Actions完美集成:自动化发布到NuGet和GitHub的终极指南 你是否厌倦了手动构建、测试、打包和发布.N
消息队列后端微服务流处理XPipe 切换中文界面完整教程:三步上手到翻译定制
XPipe 切换中文界面完整教程:三步上手到翻译定制 如果你刚把 XPipe 装到桌面,满屏英文菜单让人无从下手,这篇教程带你把界面切到中文,并弄懂背后的翻译机
消息队列流处理后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考