Skip to content
清晨的一缕阳光
返回

RocketMQ 高可用架构设计与实战

RocketMQ 的高可用架构是保障消息系统稳定运行的关键。本文将深入探讨 RocketMQ 的主从复制、Dledger、多机房部署等高可用方案。

一、高可用架构概览

1.1 整体架构

graph TB
    subgraph 可用区 A
        NS1[NameServer 1]
        B1M[Broker 1 Master]
        B2M[Broker 2 Master]
    end
    
    subgraph 可用区 B
        NS2[NameServer 2]
        B1S[Broker 1 Slave]
        B2S[Broker 2 Slave]
    end
    
    subgraph 客户端
        P[Producer]
        C[Consumer]
    end
    
    NS1 -.-> NS2
    B1M -.->|同步复制 | B1S
    B2M -.->|异步复制 | B2S
    
    P --> NS1
    P --> NS2
    C --> NS1
    C --> NS2

1.2 高可用特性

特性说明实现方式
NameServer 高可用无状态设计,多节点部署客户端轮询
Broker 高可用主从复制,自动切换Master-Slave
数据高可用多副本存储同步/异步复制
多机房容灾跨机房部署异地多活

二、主从复制

2.1 复制模式

同步复制

sequenceDiagram
    participant P as Producer
    participant M as Master
    participant S as Slave
    
    P->>M: 发送消息
    M->>S: 同步消息
    S-->>M: 确认
    M-->>P: 返回成功
    
    note over M,S: 数据强一致
# Broker Master 配置
brokerRole=SYNC_MASTER
flushDiskType=SYNC_FLUSH

# Broker Slave 配置
brokerRole=SLAVE

异步复制

sequenceDiagram
    participant P as Producer
    participant M as Master
    participant S as Slave
    
    P->>M: 发送消息
    M-->>P: 返回成功
    M->>S: 异步同步消息
    
    note over M,S: 数据最终一致
# Broker Master 配置
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH

# Broker Slave 配置
brokerRole=SLAVE

2.2 配置示例

Master 配置

# broker-a.properties

brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=0  # 0 表示 Master

namesrvAddr=ns1:9876;ns2:9876

# 复制模式
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH

# 存储路径
storePathRootDir=/data/rocketmq/store
storePathCommitLog=/data/rocketmq/store/commitlog

# 监听端口
listenPort=10911

Slave 配置

# broker-a-s.properties

brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=1  # >0 表示 Slave

namesrvAddr=ns1:9876;ns2:9876

# 从节点
brokerRole=SLAVE

# Master 地址
brokerIP1=192.168.1.100  # Master IP
masterAddress=192.168.1.100:10911

# 存储路径
storePathRootDir=/data/rocketmq/store-slave

2.3 故障切换

自动切换流程

sequenceDiagram
    participant P as Producer
    participant NS as NameServer
    participant M as Master
    participant S as Slave
    
    M --> M: 正常运行
    P->>M: 发送消息
    
    M --> M: 宕机
    NS->>NS: 检测到 Broker 下线
    NS->>P: 更新路由信息
    
    P->>S: 发送到 Slave(只读)
    note over P,S: 等待 Master 恢复
    
    M->>M: 恢复启动
    NS->>NS: 更新路由信息
    P->>M: 恢复正常发送

手动切换

#!/bin/bash
# 主从切换脚本

MASTER="broker-1"
SLAVE="broker-1-slave"

# 1. 停止 Master
echo "停止 Master..."
ssh $MASTER "systemctl stop rocketmq-broker"

# 2. 提升 Slave 为 Master
# 修改 Slave 配置
ssh $SLAVE "sed -i 's/brokerRole=SLAVE/brokerRole=ASYNC_MASTER/' /opt/rocketmq/conf/broker.conf"
ssh $SLAVE "sed -i 's/brokerId=1/brokerId=0/' /opt/rocketmq/conf/broker.conf"

# 3. 重启 Broker
ssh $SLAVE "systemctl restart rocketmq-broker"

# 4. 验证
mqadmin brokerStatus -n ns1:9876 -b $SLAVE:10911

# 5. 发送告警
sendAlert "Broker 主从切换完成:$MASTER -> $SLAVE"

三、Dledger 高可用

3.1 Dledger 架构

graph TB
    subgraph Dledger Group
        B1[Broker 1<br/>Leader]
        B2[Broker 2<br/>Follower]
        B3[Broker 3<br/>Follower]
    end
    
    P[Producer] --> B1
    C[Consumer] --> B1
    
    B1 -.->|Raft 复制 | B2
    B1 -.->|Raft 复制 | B3

3.2 Dledger 配置

Broker 1 配置

# broker-dledger-1.properties

brokerClusterName=DefaultCluster
brokerName=dledger-cluster

# Dledger 配置
enableDLegerCommitLog=true
dLegerGroup=dledger-cluster
dLegerPeers=n0-192.168.1.101:9878;n1-192.168.1.102:9878;n2-192.168.1.103:9878
dLegerSelfId=n0

# 存储路径
storePathRootDir=/data/rocketmq/store
storePathCommitLog=/data/rocketmq/store/dledger

# 监听端口
listenPort=10911

Broker 2 配置

# broker-dledger-2.properties

brokerClusterName=DefaultCluster
brokerName=dledger-cluster

# Dledger 配置
enableDLegerCommitLog=true
dLegerGroup=dledger-cluster
dLegerPeers=n0-192.168.1.101:9878;n1-192.168.1.102:9878;n2-192.168.1.103:9878
dLegerSelfId=n1

# 存储路径
storePathRootDir=/data/rocketmq/store
storePathCommitLog=/data/rocketmq/store/dledger

# 监听端口
listenPort=10912

Broker 3 配置

# broker-dledger-3.properties

brokerClusterName=DefaultCluster
brokerName=dledger-cluster

# Dledger 配置
enableDLegerCommitLog=true
dLegerGroup=dledger-cluster
dLegerPeers=n0-192.168.1.101:9878;n1-192.168.1.102:9878;n2-192.168.1.103:9878
dLegerSelfId=n2

# 存储路径
storePathRootDir=/data/rocketmq/store
storePathCommitLog=/data/rocketmq/store/dledger

# 监听端口
listenPort=10913

3.3 Leader 选举

选举流程

sequenceDiagram
    participant B1 as Broker 1
    participant B2 as Broker 2
    participant B3 as Broker 3
    
    B1->>B2: 请求投票
    B1->>B3: 请求投票
    B2-->>B1: 投票
    B3-->>B1: 投票
    B1->>B1: 成为 Leader
    
    B1->>B2: 心跳
    B1->>B3: 心跳
    
    B1 --> B1: 宕机
    B2->>B3: 请求投票
    B3-->>B2: 投票
    B2->>B2: 成为新 Leader

3.4 优缺点对比

特性主从模式Dledger 模式
一致性最终一致(异步)强一致(Raft)
可用性
故障切换手动/半自动自动
部署复杂度
性能
适用场景一般业务金融场景

四、多机房部署

4.1 同城双活

graph TB
    subgraph 机房 A
        NS1[NameServer 1]
        B1M[Broker 1 Master]
        B2M[Broker 2 Master]
    end
    
    subgraph 机房 B
        NS2[NameServer 2]
        B1S[Broker 1 Slave]
        B2S[Broker 2 Slave]
    end
    
    NS1 -.-> NS2
    B1M -.-> B1S
    B2M -.-> B2S
    
    P[Producer] --> NS1
    P --> NS2

配置要点

# 机房 A Broker 配置
brokerClusterName=DefaultCluster
brokerId=0
brokerRole=ASYNC_MASTER

# 机房 B Broker 配置
brokerClusterName=DefaultCluster
brokerId=1
brokerRole=SLAVE
masterAddress=192.168.1.100:10911  # 机房 A Master

4.2 异地多活

graph TB
    subgraph 北京机房
        NS1[NameServer 1]
        B1M[Broker 1 Master]
    end
    
    subgraph 上海机房
        NS2[NameServer 2]
        B1S[Broker 1 Slave]
    end
    
    subgraph 广州机房
        NS3[NameServer 3]
        B2M[Broker 2 Master]
    end
    
    NS1 -.-> NS2
    NS2 -.-> NS3
    
    B1M -.->|异地复制 | B1S

配置要点

# 异地复制配置
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH
flushSlaveTimeoutMillis=5000  # 增加超时时间

# 网络优化
sendHeartbeatTimeoutMillis=2000
clientChannelMaxIdleTimeSeconds=120

4.3 流量调度

DNS 调度

# DNS 配置
rocketmq.example.com  A  北京 IP
rocketmq.example.com  A  上海 IP
rocketmq.example.com  A  广州 IP

# 基于地理位置解析
北京用户 -> 北京机房
上海用户 -> 上海机房
广州用户 -> 广州机房

客户端配置

// 多 NameServer 配置
producer.setNamesrvAddr("bj-ns:9876;sh-ns:9876;gz-ns:9876");

// 故障自动切换
producer.setRetryTimesWhenSendFailed(3);
producer.setRetryAnotherBrokerWhenNotStoreOK(true);

五、容灾演练

5.1 演练场景

场景预期结果恢复时间
Broker 宕机Slave 接管,数据不丢失< 30 秒
机房故障流量切换到备用机房< 1 分钟
NameServer 故障客户端自动切换< 10 秒
网络分区数据一致,服务可用自动恢复

5.2 演练步骤

#!/bin/bash
# 容灾演练脚本

echo "=== RocketMQ 容灾演练 ==="
echo "时间:$(date)"

# 1. 模拟 Broker Master 宕机
echo -e "\n=== 步骤 1: 停止 Master ==="
ssh broker-1 "systemctl stop rocketmq-broker"
echo "Master 已停止"

# 2. 验证 Slave 接管
echo -e "\n=== 步骤 2: 验证 Slave 接管 ==="
sleep 10
mqadmin brokerStatus -n ns1:9876 -b broker-1-slave:10911

# 3. 验证生产消费
echo -e "\n=== 步骤 3: 验证生产消费 ==="
producer.sh -n ns1:9876 -t test-topic -m 100
consumer.sh -n ns1:9876 -t test-topic -g test-group

# 4. 恢复 Master
echo -e "\n=== 步骤 4: 恢复 Master ==="
ssh broker-1 "systemctl start rocketmq-broker"
sleep 30

# 5. 验证集群状态
echo -e "\n=== 步骤 5: 验证集群状态 ==="
mqadmin clusterList -n ns1:9876

echo -e "\n=== 演练完成 ==="

5.3 演练报告

# 容灾演练报告

## 演练信息
- 时间:2026-06-10 14:00-15:00
- 参与人员:运维团队、开发团队
- 演练场景:Broker Master 宕机

## 演练过程
1. 14:00 停止 Broker-1 Master
2. 14:00:30 Slave 自动接管
3. 14:01:00 验证生产消费正常
4. 14:30 恢复 Master
5. 14:30:30 集群恢复正常

## 演练结果
- ✅ Slave 在 30 秒内接管
- ✅ 数据无丢失
- ✅ 生产消费影响 < 1 分钟

## 改进建议
1. 优化监控告警响应时间
2. 完善应急预案文档
3. 增加自动化切换脚本

六、监控告警

6.1 关键指标

指标告警阈值说明
Broker 在线数< 预期数节点宕机
主从同步延迟> 1000ms同步异常
CommitLog 磁盘> 80%磁盘不足
消费堆积> 10000消费滞后

6.2 告警配置

groups:
  - name: rocketmq-ha
    rules:
      - alert: RocketMQBrokerDown
        expr: up{job="rocketmq-broker"} == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Broker 宕机:{{ $labels.instance }}"
      
      - alert: RocketMQSlaveLag
        expr: rocketmq_slave_lag > 1000
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "主从同步延迟:{{ $value }}ms"
      
      - alert: RocketMQDiskHigh
        expr: rocketmq_commitlog_disk_ratio > 80
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "磁盘使用率过高:{{ $value }}%"

七、最佳实践

7.1 部署建议

场景副本数复制方式刷盘方式
开发环境1-异步
测试环境2异步异步
生产环境2异步异步
金融场景3同步同步

7.2 运维建议

  1. 定期演练:每季度进行一次故障演练
  2. 监控告警:配置关键指标告警
  3. 备份策略:定期备份元数据
  4. 升级方案:滚动升级,避免服务中断

总结

RocketMQ 高可用架构的核心要点:

  1. 主从复制:同步/异步复制,故障切换
  2. Dledger:Raft 协议,自动选举
  3. 多机房部署:同城双活、异地多活
  4. 容灾演练:定期演练、快速恢复
  5. 监控告警:关键指标、分级告警

核心要点

参考资料


分享这篇文章到:

上一篇文章
Kafka MirrorMaker 跨集群数据同步实战
下一篇文章
Kafka Streams 实战案例精选