1. 方案总则
1.1 方案目的
为保障 RocketMQ 消息中间件服务的高可用性、数据可靠性,应对单机房故障(如机房断电、网络中断、设备故障等)导致的服务不可用问题,实现消息不丢失、业务不中断,降低故障造成的损失,特制定本双机房容灾技术方案。本方案适用于基于 RocketMQ 构建的各类业务系统,可根据业务优先级灵活调整容灾策略,满足不同场景下的可用性要求。
1.2 适用范围
本方案适用于公司所有基于 RocketMQ 部署的消息服务,涵盖核心交易、金融支付、互联网电商、日志同步等各类依赖消息中间件的业务场景;涉及双机房(同城/异地)的集群部署、消息同步、故障切换、运维监控等全流程操作,适用于技术运维人员、开发人员、架构设计人员参考执行。
1.3 核心指标
- 恢复点目标(RPO):核心业务 ≤ 1s,普通业务 ≤ 10s;金融级业务可实现 RPO ≈ 0。
- 恢复时间目标(RTO):主动切换 ≤ 3min,故障自动切换 ≤ 5min,核心业务可优化至秒级。
- 可用性:全年服务可用性 ≥ 99.99%,避免因单机房故障导致服务长时间中断。
- 数据可靠性:消息不丢失、不重复消费(除非业务允许),消费进度可同步,故障恢复后业务衔接无异常。
1.4 编制依据
基于 RocketMQ 官方文档、分布式系统容灾最佳实践、公司 IT 架构规范、业务高可用要求编制,确保方案的可行性、规范性和可落地性。
2. 现状分析与风险评估
2.1 现状概述
当前 RocketMQ 集群部署于单一机房,存在单点故障风险:当该机房发生断电、网络中断、自然灾害等异常情况时,RocketMQ 服务将全面不可用,导致消息无法生产、消费中断,进而影响全链路业务正常运行;同时,单一机房部署无法实现数据备份与冗余,一旦存储设备故障,可能造成消息永久丢失,带来严重业务损失。
2.2 核心风险
- 单机房故障风险:机房级故障(如断电、网络瘫痪)导致 RocketMQ 集群整体下线,服务不可用。
- 数据丢失风险:单一存储节点故障、磁盘损坏,未做数据备份或同步,导致消息丢失。
- 切换风险:无规范切换流程,故障发生后手动操作繁琐、易出错,延长恢复时间。
- 性能风险:跨机房消息同步占用带宽,配置不当可能导致同步延迟过高、集群性能下降。
3. 容灾方案选型
结合业务需求、成本投入、技术复杂度,RocketMQ 双机房容灾主流方案分为三类,本方案提供选型建议及详细配置,可根据业务优先级灵活选择。
3.1 方案一:主备容灾(冷备/热备,推荐通用场景)
3.1.1 架构设计
采用“主集群+备集群”架构,机房A部署主集群,承担全部消息生产与消费流量;机房B部署备集群,仅同步主集群消息,不承担业务流量(冷备)或承担少量冗余流量(热备),主备集群之间采用单向消息同步机制。
3.1.2 同步方式
- 异步复制(2m-2s-async):主集群 Broker 写入消息后,异步同步至备集群,无需等待备集群确认即可返回生产成功。优点是性能损耗小,不影响主集群吞吐量;缺点是极端情况下可能存在少量消息丢失,RPO≈秒级,适用于普通业务场景。
- 同步复制(2m-2s-sync):主集群 Broker 写入消息后,需等待备集群同步完成并确认,方可返回生产成功。优点是数据强一致,RPO≈0,无消息丢失风险;缺点是性能略有下降(吞吐量降低10%-20%),适用于金融、支付等核心业务场景。
3.1.3 适用场景
适用于大多数业务场景,尤其是核心交易、金融支付等对数据可靠性要求高,且对成本敏感、不追求极致资源利用率的场景;推荐 RTO<5min、RPO<1s 的业务优先采用。
3.1.4 优缺点
优点:架构简单、部署成本低、切换流程简洁、运维难度小;缺点:备机房资源利用率低(冷备几乎闲置),仅能应对单机房故障,无法实现业务并行承载。
3.2 方案二:双活容灾(多活,推荐高SLA场景)
3.2.1 架构设计
两机房均部署完整的 RocketMQ 集群,无主备之分,均承担业务流量(并行生产、消费);通过消息同步组件实现两集群之间的双向消息同步,确保两机房消息一致;借助动态DNS、负载均衡设备实现流量智能分配与故障无感切换。
3.2.2 关键组件
需部署消息同步组件,如 RocketMQ Replicator、MirrorMaker2、自研同步组件(基于Canal/Flume),或云厂商提供的 Global Replicator(阿里云)、TDMQ 跨地域同步(腾讯云);核心能力包括:双向消息同步、消费进度同步、防循环复制、顺序消息保障、异常重试机制。
3.2.3 适用场景
适用于互联网、电商、直播等对服务可用性要求极高(SLA≥99.99%)、无单点故障容忍度、需要业务连续运行的场景;适合业务流量大、资源利用率要求高的场景。
3.2.4 优缺点
优点:资源利用率高(两机房均承载业务)、故障无感切换(RTO≈秒级)、业务连续性强;缺点:技术复杂度高,需解决循环复制、消费幂等、顺序消息一致性等问题,运维成本高。
3.3 方案三:Dledger/Controller 跨机房自动切换(推荐同城双机房场景)
3.3.1 架构设计
Broker 节点跨机房部署,例如机房A部署1个 Master 节点,机房B部署2个 Slave 节点,组成 Dledger 三副本集群;基于 Raft 协议实现集群选举,当主机房(A机房)故障时,自动从备机房(B机房)的 Slave 节点中选举新的 Master,实现故障自动转移。
3.3.2 核心原理
Dledger 作为 RocketMQ 的分布式日志存储组件,通过三副本机制(跨机房部署)保障数据可靠性;Raft 协议要求集群中多数派(2/3)节点存活即可正常提供服务,因此单机房故障(最多1个副本所在机房下线)时,集群可自动选举新主,无需人工干预。
3.3.3 适用场景
适用于同城双机房场景(网络延迟低),对数据强一致性、自动故障转移要求高,且不希望投入过多人工运维成本的场景;适合 RTO≈秒级、RPO≈0 的核心业务。
3.3.4 优缺点
优点:无需人工干预,故障自动切换,RTO≈秒级;数据强一致,RPO≈0;运维成本较低;缺点:对网络延迟敏感(要求跨机房延迟<5ms),跨机房带宽要求高,仅适合同城双机房部署。
3.4 方案选型建议
- 中小业务、通用场景:优先选择主备容灾(异步复制),兼顾可靠性与成本,部署运维简单。
- 金融、支付等核心业务:选择主备容灾(同步复制)+ Dledger 跨机房部署,实现强一致性与自动切换,保障数据零丢失。
- 互联网、高SLA业务:选择双活容灾,实现业务无感切换与高资源利用率,满足连续服务需求。
4. 核心组件部署方案
无论选择哪种容灾方案,均需满足以下核心组件的跨机房部署要求,确保集群高可用;以下以主备容灾(同步复制)为例,给出标准部署方案,其他方案可在此基础上调整。
4.1 NameServer 部署(无状态组件,必选跨机房)
4.1.1 部署规格
采用跨机房部署,机房A部署2台 NameServer 节点,机房B部署2台 NameServer 节点,组成4节点集群;节点配置:CPU≥4核、内存≥8G、磁盘≥100G(SSD),确保节点性能稳定。
4.1.2 核心配置
所有 Producer、Consumer 需配置全部4个 NameServer 地址(机房A 2个+机房B 2个),配置示例如下:
namesrvAddr=ipA1:9876,ipA2:9876,ipB1:9876,ipB2:9876
4.1.3 核心作用
NameServer 作为 RocketMQ 的路由注册中心,无状态、可水平扩展;跨机房部署可确保单机房故障时,路由服务不中断,Producer、Consumer 可通过另一机房的 NameServer 获取 Broker 路由信息,保障服务连续性。
4.2 Broker 集群部署(核心组件)
4.2.1 主备容灾(2m-2s-sync)部署
- 机房A(主集群):部署 broker-a-master、broker-b-master 两个 Master 节点,承担消息生产与消费主流量。
- 机房B(备集群):部署 broker-a-slave、broker-b-slave 两个 Slave 节点,仅同步主集群消息,作为备用节点。
- 节点配置:CPU≥8核、内存≥16G、磁盘≥500G(SSD,用于存储 commitlog、consumequeue 等数据),核心配置如下:
# Master 节点配置(机房A)
brokerRole=SYNC_MASTER
flushDiskType=SYNC_FLUSH # 金融级配置,确保消息刷盘后再返回成功
haSendMessageOKTimes=1 # 至少1个 Slave 节点同步成功后,Master 才返回生产成功
brokerName=broker-a/b
listenPort=10911
storePathRootDir=/data/rocketmq/store
# Slave 节点配置(机房B)
brokerRole=SLAVE
flushDiskType=SYNC_FLUSH
haMasterAddress=ipA1:10911,ipA2:10911 # 指向对应 Master 节点地址
brokerName=broker-a/b # 与 Master 节点 brokerName 一致,确保同步生效
listenPort=10911
storePathRootDir=/data/rocketmq/store
4.2.2 Dledger 跨机房部署(3副本)
- 节点分布:机房A部署1个节点(n0),机房B部署2个节点(n1、n2),组成3副本 Dledger 集群。
- 核心配置(以机房A n0节点为例):
enableDLegerCommitLog=true # 开启 Dledger 分布式日志
dLegerGroup=broker-a # 同一 Dledger 集群组名一致
dLegerPeers=n0-ipA:40911,n1-ipB:40911,n2-ipB:40911 # 所有节点地址(格式:节点ID-IP:端口)
dLegerSelfId=n0 # 当前节点ID,与 dLegerPeers 中的节点ID对应
brokerRole=DLegerGroupMaster # Dledger 集群主节点(自动选举,无需手动指定)
flushDiskType=SYNC_FLUSH
4.3 消息同步组件部署
4.3.1 组件选型
- 开源方案:优先选择 RocketMQ Replicator(官方跨集群同步组件),支持消息同步、消费进度同步,配置简单;其次可选择 MirrorMaker2、自研同步组件(基于 Canal/Flume 实现)。
- 云厂商方案:若使用云服务器部署,可选择阿里云 Global Replicator、腾讯云 TDMQ 跨地域同步组件,支持双向同步、故障自动重试,运维成本低。
4.3.2 核心配置(以 RocketMQ Replicator 为例)
实现主备集群单向同步(机房A→机房B),核心配置如下,需避免循环复制:
# 源集群(机房A)配置
source.namesrvAddr=ipA1:9876,ipA2:9876
source.topic=* # 同步所有 Topic,可指定具体 Topic
source.group=replicator-group
# 目标集群(机房B)配置
target.namesrvAddr=ipB1:9876,ipB2:9876
target.topic=* # 与源 Topic 一致,确保消息同步后可正常消费
# 防循环复制配置
filter.replicateMsg=true
filter.replicateMsg.tag=REPLICATE # 给同步消息打标签,避免回传
filter.replicateMsg.ignore=true # 忽略带有 REPLICATE 标签的消息,防止循环
4.4 监控与告警组件部署
部署 Prometheus+Grafana 监控体系,跨机房部署监控节点,确保可监控两个机房的 RocketMQ 集群状态,核心监控指标及告警配置如下:
- 监控指标:NameServer 节点存活状态、Broker 节点存活状态、消息同步延迟、消息堆积量、生产/消费吞吐量、刷盘延迟、消费进度差。
- 告警配置:当节点下线、同步延迟>1s、消息堆积>10000条、消费进度差>1000条时,触发告警(短信、邮件、企业微信通知),确保运维人员及时响应。
5. 完整容灾架构图(主备容灾示例)
以下为 RocketMQ 双机房主备容灾(同步复制)完整架构,清晰展示各组件部署关系、消息流向及流量切换逻辑:
机房A(主集群) 机房B(备集群)
┌─────────────┐ ┌─────────────┐
│ NameServer │ │ NameServer │
│ 2节点 │←--------→│ 2节点 │ # 跨机房路由同步
└─────────────┘ └─────────────┘
↑ ↑
│ │
┌─────────────┐ ┌─────────────┐
│ Broker │ │ Broker │
│ 2主(a,b) │←消息同步→│ 2从(a,b) │ # 主备同步(SYNC_MASTER)
└─────────────┘ └─────────────┘
↑ ↑
│ │
┌─────────────┐ ┌─────────────┐
│ Producer │ │ Producer │
│ 主写A │ │ 备写B │ # 正常情况下主写A,故障时切至B
└─────────────┘ └─────────────┘
↑ ↑
│ │
┌─────────────┐ ┌─────────────┐
│ Consumer │ │ Consumer │
│ 主消费A │ │ 备消费B │ # 正常情况下主消费A,故障时切至B
└─────────────┘ └─────────────┘
↑ ↑
└─────────┬─────────────┘
│
┌─────────────┐
│ 监控节点 │ # Prometheus+Grafana,跨机房监控
│(A/B机房各1台)│
└─────────────┘
↓
┌─────────────┐
│ 告警系统 │ # 异常情况触发多渠道告警
└─────────────┘
补充说明:流量入口通过 VIP/动态DNS实现,默认指向机房A(主集群);当机房A故障时,通过切换 DNS/VIP,将流量快速切换至机房B(备集群),实现业务恢复。
6. 故障切换流程
故障切换分为主动切换(日常维护)和被动切换(机房故障)两种场景,需严格遵循流程执行,确保切换过程无消息丢失、无业务中断,以下以主备容灾方案为例。
6.1 主动切换(日常维护场景)
当需要对机房A(主集群)进行设备维护、系统升级时,执行主动切换,流程如下:
- 准备工作:确认备集群(机房B)消息同步完成,同步延迟≤0,消费进度与主集群一致;备份主集群所有配置文件、数据文件,避免切换异常。
- 停止主集群写入:暂停机房A所有 Producer 服务,停止向主集群写入消息;等待主集群现有消息全部消费完成,确保无消息堆积。
- 验证备集群状态:检查机房B备集群 Broker 节点、NameServer 节点正常运行,消息同步无延迟,消费组件可正常启动。
- 流量切换:通过动态DNS/VIP,将所有 Producer、Consumer 流量切换至机房B(备集群);修改 Producer 配置,指向机房B NameServer 地址,启动 Producer 写入。
- 验证业务:检查消息生产、消费正常,无消息丢失、重复消费,业务流程衔接正常;监控备集群各项指标(吞吐量、堆积量、同步状态)。
- 完成切换:确认业务无异常后,停止机房A主集群服务,进行维护操作;维护完成后,可按反向流程切换回主集群,或保持备集群作为主集群运行。
6.2 被动切换(机房故障场景)
当机房A(主集群)发生故障(断电、网络中断、所有节点下线)时,执行被动切换,流程如下:
- 告警响应:监控系统触发告警,运维人员确认机房A故障(无法访问、节点全部下线),启动应急切换流程。
- 紧急切换流量:立即通过动态DNS/VIP,将所有 Producer、Consumer 流量切换至机房B(备集群);无需等待主集群恢复,优先保障业务连续性。
- 重置消费位点:检查备集群消息同步情况,将 Consumer 消费位点重置至最后同步成功的位点,避免消息重复消费或丢失。
- 启动业务组件:启动机房B备集群的 Producer、Consumer 服务,修改配置指向机房B NameServer 地址,确保消息正常生产、消费。
- 业务验证:检查核心业务流程,确认消息无丢失、消费正常,监控备集群各项指标,确保无异常。
- 故障排查与恢复:排查机房A故障原因,修复故障后,启动主集群服务,同步备集群消息(反向同步),待同步完成后,可根据业务需求切换回主集群,或保持备集群运行。
6.3 切换注意事项
- 切换前必须确认备集群消息同步完成(主动切换),避免消息丢失;被动切换需优先保障业务连续性,后续再进行数据对账。
- 切换过程中,需暂停消息生产(主动切换),避免切换期间消息写入异常;被动切换可直接启动备集群生产,无需暂停。
- 切换后需重点监控消息堆积、消费进度,及时处理异常,确保业务无中断。
- 每季度进行1次切换演练,熟悉切换流程,避免故障发生时操作失误。
7. 关键配置与最佳实践
7.1 消息可靠性保障配置
- 刷盘配置:核心业务(金融、支付)采用
SYNC_FLUSH(同步刷盘),确保消息写入磁盘后再返回成功;普通业务可采用ASYNC_FLUSH(异步刷盘),兼顾性能与可靠性。 - 复制配置:主备容灾场景,核心业务采用
SYNC_MASTER(同步复制),普通业务采用ASYNC_MASTER(异步复制);双活场景采用异步复制+重试机制,避免影响性能。 - 数据备份:每日凌晨对 Broker 存储目录(
store/)进行全量备份,保留30天以上;核心业务可增加增量备份,确保数据可恢复。 - 消息重试:Producer 配置重试机制(
retryTimesWhenSendFailed=3),避免因网络波动导致消息发送失败;Consumer 配置重试3次+死信队列,处理消费失败的消息,避免消息堆积。
7.2 消费端保障实践
- 消费幂等:通过消息唯一ID(
msgId)+ 业务主键(如订单ID)实现消费幂等,避免切换过程中出现重复消费,影响业务数据一致性。 - 消费进度同步:双活场景需部署消费进度同步组件,确保两机房 Consumer 消费进度一致,切换后无需重新消费历史消息。
- 顺序消息保障:双活场景按 Topic/Queue 分区同步消息,确保同一 Queue 的消息顺序不变;避免跨分区同步导致顺序错乱。
7.3 网络与性能优化
- 网络配置:同城双机房采用专线连接,确保跨机房延迟<5ms;异地双机房采用跨城专线,带宽≥100M,确保消息同步延迟<1s。
- 带宽限流:消息同步组件配置限流机制,避免同步流量打满跨机房带宽,影响业务流量;可根据业务吞吐量调整限流阈值。
- 集群优化:Broker 节点采用 SSD 磁盘,提升消息刷盘、读取性能;合理设置 Queue 数量(每个 Topic Queue 数量≥4),提升并发处理能力。
7.4 运维最佳实践
- 定期演练:每月进行1次故障切换演练,每季度进行1次全流程容灾演练,验证方案可行性,优化切换流程。
- 日常监控:实时监控跨机房同步延迟、消息堆积、节点状态,建立监控看板,及时发现异常。
- 配置管理:所有节点配置文件统一管理,修改配置后需重启节点,并同步至所有相关组件,避免配置不一致。
- 故障排查:建立故障排查手册,明确各类异常(同步延迟过高、消息丢失、切换失败)的排查步骤,提高响应效率。
8. 方案对比与选型表
| 容灾方案 | 技术复杂度 | RPO | RTO | 资源利用率 | 适用场景 | 运维成本 |
|---|---|---|---|---|---|---|
| 主备(异步复制) | 低 | 秒级 | 5min | 低 | 通用业务、中小业务 | 低 |
| 主备(同步复制) | 中 | ≈0 | 3min | 低 | 金融、支付、核心交易 | 中 |
| Dledger 跨机房 | 中 | ≈0 | 秒级 | 中 | 同城双机房、核心业务 | 中 |
| 双活(双向同步) | 高 | 秒级 | 秒级 | 高 | 互联网、高SLA业务 | 高 |
9. 实施步骤
- 前期准备(1-2天):打通双机房网络(专线/VPN),确保跨机房网络连通性、延迟达标;梳理业务需求,确定容灾方案选型;备份现有 RocketMQ 集群数据与配置。
- NameServer 部署(1天):在两机房分别部署 NameServer 节点,配置跨机房节点地址,启动集群,验证路由同步正常。
- Broker 集群部署(2-3天):根据选型方案,部署主备/Dledger Broker 集群,配置主从同步、Dledger 副本等参数,启动集群,验证节点存活、消息同步正常。
- 同步组件部署(1天):部署消息同步组件(Replicator/MirrorMaker2),配置同步规则、防循环复制参数,验证消息同步正常(无丢失、无延迟)。
- 业务适配(2-3天):修改 Producer、Consumer 配置,添加双机房 NameServer 地址;实现消费幂等、消费进度同步(双活场景);测试业务生产、消费正常。
- 监控告警部署(1天):部署 Prometheus+Grafana 监控体系,配置监控指标、告警规则,测试告警正常触发。
- 演练与优化(1-2天):进行故障切换演练(主动+被动),排查问题并优化;调整同步延迟、限流阈值等参数,确保方案满足核心指标。
- 上线运行:确认所有组件正常运行、业务适配完成、演练通过后,正式上线容灾方案,进入日常运维阶段。
10. 常见问题与解决方案
| 常见问题 | 产生原因 | 解决方案 |
|---|---|---|
| 消息循环复制 | 双活场景双向同步,消息从A机房同步至B机房后,又被同步回A机房 | 同步组件配置过滤规则,给同步消息打专属标签(如 REPLICATE),忽略带有该标签的消息,避免循环 |
| 顺序消息错乱 | 双活场景跨 Queue 同步消息,破坏消息顺序;同步延迟导致顺序颠倒 | 按 Topic/Queue 分区同步消息,确保同一 Queue 消息顺序不变;优化网络,降低同步延迟 |
| 数据不一致 | 同步组件故障、网络中断导致消息同步失败;主备切换时未确认同步状态 | 定期对账(每日),对比主备集群消息数量、消费进度;同步组件配置重试机制,故障恢复后自动补同步;切换前确认同步完成 |
| 切换失败 | 配置错误、备集群状态异常、切换流程不规范;未进行演练 | 提前进行切换演练,熟悉流程;切换前检查备集群状态、配置一致性;准备手动切位点脚本,应对异常情况 |
| 同步延迟过高 | 跨机房带宽不足、同步组件限流过低、Broker 性能不足 | 提升跨机房带宽;调整同步组件限流阈值;优化 Broker 配置(SSD 磁盘、增加内存) |
11. 风险控制与应急预案
11.1 风险控制措施
- 网络风险:双机房专线备份(主专线+备用VPN),避免专线中断导致同步失败;定期检测网络延迟、带宽利用率,及时扩容。
- 组件风险:关键组件(NameServer、Broker、同步组件)均采用多节点部署,避免单点故障;定期检查组件运行状态,及时修复异常节点。
- 数据风险:定期备份数据,保留足够备份周期;核心业务采用同步复制、同步刷盘,确保数据零丢失;建立数据对账机制,及时发现并修复数据不一致。
- 操作风险:规范切换流程,明确操作步骤与责任人;定期进行操作培训与演练,避免人为失误;重要操作前备份配置与数据。
11.2 应急预案
11.2.1 机房级故障应急预案
当某一机房整体故障时,立即启动被动切换流程,运维人员10分钟内响应,30分钟内完成流量切换,确保业务恢复;故障恢复后,同步数据,验证无误后切换回正常集群。
11.2.2 同步组件故障应急预案
当消息同步组件故障时,立即启动备用同步组件(如部署双实例),暂停主集群消息写入(核心业务可切换至备集群写入),修复故障组件后,进行消息补同步,确保数据一致。
11.2.3 消息丢失应急预案
当发现消息丢失时,立即停止相关业务生产,通过备份数据恢复丢失的消息;排查丢失原因(同步故障、刷盘失败等),修复问题后,重启业务生产,验证消息生产、消费正常。
12. 方案总结与后续优化
12.1 方案总结
本方案基于 RocketMQ 双机房容灾需求,提供了主备容灾、双活容灾、Dledger 跨机房容灾三种选型方案,明确了各方案的架构设计、部署配置、切换流程及最佳实践;方案兼顾了业务可靠性、成本投入与运维难度,可根据不同业务场景灵活选择,能够有效应对单机房故障,保障消息服务高可用、数据零丢失,满足公司各类业务的高可用性要求。