导语

RocketMQ 是一款分布式消息中间件,广泛应用于高并发与高可靠场景。在早期版本中,集群部署通常采用 Master/Slave 主从模式,这种架构虽然能够实现数据副本冗余,但存在以下问题:

  • 故障切换依赖人工:当 Master 宕机时,需要手动指定新的 Master,恢复慢。
  • 一致性难以保障:异步复制可能造成数据丢失,强同步复制又影响性能。
  • 客户端感知复杂:Producer 和 Consumer 需要区分 Master 与 Slave,运维成本高。

为解决这些问题,RocketMQ 在 4.5 版本引入了 DLedger 模式,并在 5.x 版本中成为官方推荐的高可用部署方案。DLedger 基于 Raft 协议实现:

  • 自动选主:Leader 节点故障时,Follower 会自动发起选举并接管,无需人工干预;
  • 强一致性:消息写入需得到多数节点确认才成功,避免丢失;
  • 对客户端透明:外部只需感知逻辑 Broker,不必关心 Master/Slave;

运维简化:所有节点配置几乎一致,仅通过 dLegerSelfId 区分节点身份,Topic 也只需创建一次即可在组内自动保持一致。

1. 构建自定义镜像

1.1 准备 Dockerfile

在项目目录下创建 Dockerfile

FROM dw14132124/ubuntu22-base

ARG ROCKETMQ_VERSION=5.3.1
ENV ROCKETMQ_HOME=/workspace/rocketmq
ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
ENV PATH=$JAVA_HOME/bin:$ROCKETMQ_HOME/bin:$PATH
ENV HTTP_PROXY=http://11.11.11.1:10809
ENV HTTPS_PROXY=http://11.11.11.1:10809

RUN apt-get update && apt-get install -y openjdk-11-jdk unzip \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /workspace

RUN wget https://mirrors.tuna.tsinghua.edu.cn/apache/rocketmq/${ROCKETMQ_VERSION}/rocketmq-all-${ROCKETMQ_VERSION}-bin-release.zip -O /tmp/rmq.zip && \
    unzip /tmp/rmq.zip -d /workspace && \
    mv /workspace/rocketmq-all-${ROCKETMQ_VERSION}-bin-release $ROCKETMQ_HOME && \
    rm -f /tmp/rmq.zip

CMD ["tail", "-f", "/dev/null"]

1.2 构建镜像

执行以下命令:

docker build -t dw14132124/rocketmq-ub .

2 docker-compose.yml

services:
  # ---------------- NameServers ----------------
  rmq-namesrv1:
    image: dw14132124/rocketmq-ub
    container_name: rmq-namesrv1
    command: sh -c "sh /workspace/rocketmq/bin/mqnamesrv"
    networks:
      lan10:
        ipv4_address: 17.11.100.60

  rmq-namesrv2:
    image: dw14132124/rocketmq-ub
    container_name: rmq-namesrv2
    command: sh -c "sh /workspace/rocketmq/bin/mqnamesrv"
    networks:
      lan10:
        ipv4_address: 17.11.100.61

  # ---------------- Brokers (DLedger Group) ----------------
  rmq-broker1:
    image: dw14132124/rocketmq-ub
    container_name: rmq-broker1
    volumes:
      - ./brokers/broker1/store:/workspace/rocketmq/store
      - ./brokers/broker1/broker.conf:/workspace/rocketmq/conf/broker.conf:ro
    command: sh -c "sh /workspace/rocketmq/bin/mqbroker -c /workspace/rocketmq/conf/broker.conf"
    depends_on:
      - rmq-namesrv1
      - rmq-namesrv2
    networks:
      lan10:
        ipv4_address: 17.11.100.70

  rmq-broker2:
    image: dw14132124/rocketmq-ub
    container_name: rmq-broker2
    volumes:
      - ./brokers/broker2/store:/workspace/rocketmq/store
      - ./brokers/broker2/broker.conf:/workspace/rocketmq/conf/broker.conf:ro
    command: sh -c "sh /workspace/rocketmq/bin/mqbroker -c /workspace/rocketmq/conf/broker.conf"
    depends_on:
      - rmq-namesrv1
      - rmq-namesrv2
    networks:
      lan10:
        ipv4_address: 17.11.100.71

  rmq-broker3:
    image: dw14132124/rocketmq-ub
    container_name: rmq-broker3
    volumes:
      - ./brokers/broker3/store:/workspace/rocketmq/store
      - ./brokers/broker3/broker.conf:/workspace/rocketmq/conf/broker.conf:ro
    command: sh -c "sh /workspace/rocketmq/bin/mqbroker -c /workspace/rocketmq/conf/broker.conf"
    depends_on:
      - rmq-namesrv1
      - rmq-namesrv2
    networks:
      lan10:
        ipv4_address: 17.11.100.72

  # ---------------- Dashboard ----------------
  rmq-dashboard:
    image: apacherocketmq/rocketmq-dashboard:latest
    container_name: rmq-dashboard
    environment:
      JAVA_OPTS: >
        -Dserver.port=80
        -Drocketmq.namesrv.addr=17.11.100.60:9876;17.11.100.61:9876
    depends_on:
      - rmq-namesrv1
      - rmq-namesrv2
    networks:
      lan10:
        ipv4_address: 17.11.100.80

networks:
  lan10:
    external: true

3. Broker 配置示例

./brokers/broker1/broker.conf

# 集群名(同一集群内的 broker 要保持一致)
brokerClusterName=rmq-cluster

# 在 DLedger 模式下,一个组的所有节点共享同一个 brokerName(如 broker-a)。
# 如果要扩展多个组,可以用 broker-b、broker-c
brokerName=broker-a

# Broker 对外服务端口(Producer/Consumer 连接用,默认 10911)
listenPort=10911

# NameServer 地址列表(多个用分号分隔)
# Broker 启动后会向所有 NameServer 注册
# Producer/Consumer 也通过这些地址发现路由。
namesrvAddr=17.11.100.60:9876;17.11.100.61:9876

# 消息存储的根目录
storePathRootDir=/workspace/rocketmq/store

# 顺序写入消息存储文件
storePathCommitLog=/workspace/rocketmq/store/commitlog

# 逻辑消费队列,加速消息检索
storePathConsumeQueue=/workspace/rocketmq/store/consumequeue

# 消息索引,支持 key 查询
storePathIndex=/workspace/rocketmq/store/index

# 启用 DLedger 存储引擎
# 启用后,Broker 不再使用传统 Master/Slave 模式
# 所有写入通过 Raft 协议保证强一致
enableDLegerCommitLog=true

# DLedger组名,一个组内的节点构成一个强一致副本集
dLegerGroup=group1

# DLedger 节点列表
# 格式:节点ID-IP:端口
# 注意:所有节点的 dLegerPeers 配置必须一致
dLegerPeers=n0-17.11.100.70:40911;n1-17.11.100.71:40911;n2-17.11.100.72:40911

# 当前 Broker 节点在组内的 ID
# broker1 填 n0,broker2 填 n1,broker3 填 n2
dLegerSelfId=n0

broker2/broker.confbroker3/broker.conf 的区别仅在于:

  • dLegerSelfId=n1
  • dLegerSelfId=n2

3.4 验证与测试

3.4.1 启动
docker compose up -d
3.4.2 查看集群状态
docker exec -it rmq-broker1 sh /workspace/rocketmq/bin/mqadmin clusterList -n 17.11.100.60:9876
    #Cluster Name           #Broker Name            #BID  #Addr                  #Version              #InTPS(LOAD)     #OutTPS(LOAD)  #Timer(Progress)        #PCWait(ms)  #Hour         #SPACE    #ACTIVATED
    rmq-cluster             broker-a                0     17.11.100.70:10911     V5_3_1                 0.00(0,0ms)       0.00(0,0ms)  0-0(0.0w, 0.0, 0.0)               0  488029.06     0.1200          true
    rmq-cluster             broker-a                2     17.11.100.71:10911     V5_3_1                 0.00(0,0ms)       0.00(0,0ms)  2-0(0.0w, 0.0, 0.0)               0  488029.06     0.1200         false
    rmq-cluster             broker-a                3     17.11.100.72:10911     V5_3_1                 0.00(0,0ms)       0.00(0,0ms)  1-0(0.0w, 0.0, 0.0)               0  488029.06     0.1200         false

DLedger 模式下,整个 Broker 组对外表现为一个逻辑 Broker,其中只有 1 个节点会被选举为 Leader,负责对外处理写入与读请求,其余节点作为 Follower 执行日志复制以保证数据强一致;当 Leader 宕机时,Follower 会自动发起选举并接管成为新的 Leader,从而实现 高可用与强一致

3.4.3 创建 Topic
docker exec -it rmq-broker1 sh /workspace/rocketmq/bin/mqadmin updateTopic \
      -n 17.11.100.60:9876 \
      -c rmq-cluster \
      -t TestTopic
3.4.4 查看 Dashboard

浏览器访问:

http://17.11.100.80
Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐