Skip to content

Docker 部署 RocketMQ:搭建单节点消息队列与 Proxy 接入端点

Apache RocketMQ 是面向分布式应用的消息与流平台。下面的配置在一台主机上运行 NameServer、单 Broker 和 Proxy,适合本地开发、集成测试、功能验证和可信内网中的低风险单机服务。

正式部署采用官方 Compose 快速开始明确使用的 5.3.2 镜像契约。RocketMQ 5.5.1 已于 2026-08-20 发布,但官方 Compose 快速开始仍以 5.3.2 为示例;升级到其他版本前,应重新核对镜像、配置兼容性和发布说明,不能只替换镜像标签。

部署结论

项目本文采用的值
GitHub 地址apache/rocketmq
官方镜像apache/rocketmq:5.3.2
项目版本5.3.2
正式部署Docker Compose,NameServer + Broker + Proxy
快速体验不提供:RocketMQ 需要多个角色协作,单容器命令不能覆盖正式运行链路
适用范围本地开发、集成测试、功能验证、可信内网单机服务
主机架构官方 Compose 页面要求 64 位操作系统;当前环境未取得镜像 manifest,具体 CPU 架构需在目标主机拉取前确认
最低资源官方 Compose 页面未给出统一 CPU、内存和磁盘下限;容量取决于消息大小、保留时间和吞吐量
对外端口9876 NameServer、10909/10911/10912 Broker、8080/8081 Proxy;可选 Dashboard 使用 8082,默认只绑定 127.0.0.1
持久化位置rocketmq-namesrv-logsrocketmq-broker-logsrocketmq-broker-store Docker 卷
依赖服务无独立数据库或缓存;客户端推荐通过 Proxy 8081 接入;Dashboard 为可选管理组件
验证范围官方仓库、Docker 仓库、Compose 文档与发布说明核对;Compose 静态校验;未拉取镜像、未启动容器
部署日期2026-09-02

这套 Compose 是单节点、单副本拓扑。Broker 或宿主机故障会中断服务,单份消息存储也不构成高可用或灾难恢复方案;生产集群应按官方部署文档规划多 NameServer、多 Broker 副本、监控、容量和跨主机备份。

运行结构

NameServer 保存路由元数据,Broker 负责消息存储和投递,Proxy 为 RocketMQ 5.x gRPC 客户端提供统一接入端点。Broker 的消息、消费进度和运行元数据写入 /home/rocketmq/store,由独立数据卷跨容器重建保留。

Mermaid 流程图
查看源码
flowchart LR
  Client[生产者与消费者] -->|127.0.0.1:8081| Proxy[RocketMQ Proxy]
  Admin[容器内 mqadmin] --> NameServer[NameServer :9876]
  Dashboard[可选 Dashboard :8082] --> NameServer
  Dashboard --> Broker
  Proxy --> NameServer
  Proxy --> Broker[Broker :10909/:10911/:10912]
  Broker --> NameServer
  Broker --> Store[(rocketmq-broker-store)]

Proxy 的 80808081 来自官方 Compose 示例。RocketMQ 5.x Java 客户端示例通常把 endpoint 设置为 localhost:8081。经典 Remoting 客户端需要从 NameServer 获取 Broker 地址,涉及 brokerIP1、主机路由和防火墙配置;本文的默认路径不把经典 Remoting 端口开放到局域网或公网。

核心组件职责

  • NameServer:轻量、无状态的路由注册中心。Broker 定期向 NameServer 注册并发送心跳,Producer、Consumer、Proxy 和管理工具通过 NameServer 查询 Topic 与 Broker 路由。NameServer 不保存消息正文,也不代替 Broker 转发业务消息;部署多个 NameServer 时,各节点彼此独立,Broker 和客户端需要配置完整地址列表。
  • Broker:RocketMQ 的消息数据面,负责接收 Producer 消息、持久化 CommitLog、构建消费队列与索引、处理 Consumer 拉取、维护消费进度并执行重试、延迟和过滤等服务端逻辑。单 Broker 只有一份运行实例和存储,不具备节点级高可用。
  • Proxy:RocketMQ 5.x 的统一接入层。gRPC 客户端只连接 Proxy,由 Proxy 查询 NameServer 并访问 Broker;Proxy 不保存消息正文,不能替代 Broker 数据卷和消息备份。
  • Dashboard:可选的 Web 管理界面,提供集群、Topic、Consumer、消息查询和部分配置操作。Dashboard 通过 NameServer 和 Broker 管理 RocketMQ,不是消息链路必需组件,也不能替代监控告警、审计或备份。

RocketMQ 5.x 之后的客户端与部署变化

RocketMQ 5.x 没有废弃原有 Remoting 客户端,而是在保留经典接入方式的同时增加了 gRPC 客户端和 Proxy。服务端升级到 5.x 不代表应用必须改用 Proxy;应根据客户端依赖、语言、网络边界和迁移成本选择接入方式。

对比项经典 Remoting 客户端RocketMQ 5.x gRPC 客户端
Java 依赖org.apache.rocketmq:rocketmq-client,常见于 RocketMQ Spring Starterorg.apache.rocketmq:rocketmq-client-java
服务端兼容范围RocketMQ 4.x 和 5.xRocketMQ 5.0 及以上
应用配置NameServer 地址,例如 namesrv:9876Proxy endpoint,例如 proxy:8081
调用链应用查询 NameServer,再直连 Broker应用只连接 Proxy,由 Proxy 访问 NameServer 和 Broker
网络要求应用必须能访问 NameServer 和路由中返回的 Broker 地址应用只需访问 Proxy,NameServer 和 Broker 可留在内部网络
适用情况已有 Java 项目、平滑升级、依赖经典管理与消费接口新建 5.x 项目、多语言 SDK、容器或跨网段接入

Proxy 带来的变化

  • 稳定入口:应用只保存一个或一组 Proxy endpoint。Broker 扩容、迁移或容器地址变化不再直接暴露给客户端。
  • 缩小网络开放面:外部应用可以只访问 Proxy,NameServer 和 Broker 端口保留在 Docker 网络或可信内网。
  • 统一多语言协议:RocketMQ 5.0 新增的 gRPC 客户端独立演进,官方 SDK 覆盖 Java、C/C++、.NET、Go 和 Rust 等语言。
  • 集中接入治理:Proxy 可以作为 ACL、TLS、流量入口、访问日志和监控的集中位置,但认证和加密仍需显式配置。
  • 独立扩缩容:Proxy 不保存消息正文,消息数据仍由 Broker 持久化。Cluster 模式可以增加多个 Proxy 实例并在客户端或内部负载均衡层配置多个 endpoint。

Proxy 也会增加一次网络转发,并占用独立的 CPU、内存和连接资源。单个 Proxy 容器是接入单点;生产环境使用 gRPC 路径时,应部署多个 Proxy 实例并验证客户端故障切换,不能把 restart: on-failure 当成高可用。

Local 与 Cluster 两种模式

RocketMQ 5.x 官方部署文档给出两种 Proxy 形态:

  • Local 模式:Proxy 与 Broker 在同一进程中运行,适合从早期版本平滑升级或不需要独立扩缩容的部署。
  • Cluster 模式:Proxy 与 Broker 分开部署,Proxy 通过 NameServer 查找 Broker,适合独立扩缩容和隔离外部接入。

本文 Compose 使用独立 proxy 服务,属于 Cluster 模式。Cluster 模式让 Broker 继续专注于消息存储,但增加了需要监控和保障可用性的 Proxy 组件。

部署前准备

准备一台 64 位 Linux 主机,安装 Docker Engine 和 Docker Compose v2。容器镜像已包含 Java 运行时,宿主机不需要单独为这套部署安装 JDK。

bash
docker --version
docker compose version
docker info --format '{{.Architecture}}'

确认部署端口没有被占用:

bash
ss -lntp | grep -E ':(9876|8080|8081|10909|10911|10912)\b'

没有输出通常表示这些端口空闲。已有监听者时先确认进程用途,再修改 Compose 左侧的宿主机端口;不要直接终止来源不明的进程。

创建工作目录:

bash
mkdir -p "$HOME/apps/rocketmq/backups"
cd "$HOME/apps/rocketmq"

Docker Compose 正式部署

将下面内容保存为 $HOME/apps/rocketmq/compose.yaml

yaml
name: rocketmq

services:
  namesrv:
    image: apache/rocketmq:5.3.2
    container_name: rmqnamesrv
    restart: unless-stopped
    command: sh mqnamesrv
    ports:
      - "127.0.0.1:9876:9876"
    volumes:
      - namesrv-logs:/home/rocketmq/logs
    networks:
      - rocketmq
    logging:
      driver: json-file
      options:
        max-size: "20m"
        max-file: "5"

  broker:
    image: apache/rocketmq:5.3.2
    container_name: rmqbroker
    restart: unless-stopped
    command: sh mqbroker
    environment:
      NAMESRV_ADDR: namesrv:9876
    depends_on:
      - namesrv
    ports:
      - "127.0.0.1:10909:10909"
      - "127.0.0.1:10911:10911"
      - "127.0.0.1:10912:10912"
    volumes:
      - broker-logs:/home/rocketmq/logs
      - broker-store:/home/rocketmq/store
    networks:
      - rocketmq
    logging:
      driver: json-file
      options:
        max-size: "20m"
        max-file: "5"

  proxy:
    image: apache/rocketmq:5.3.2
    container_name: rmqproxy
    restart: on-failure
    command: sh mqproxy
    environment:
      NAMESRV_ADDR: namesrv:9876
    depends_on:
      - namesrv
      - broker
    ports:
      - "127.0.0.1:8080:8080"
      - "127.0.0.1:8081:8081"
    networks:
      - rocketmq
    logging:
      driver: json-file
      options:
        max-size: "20m"
        max-file: "5"

  dashboard:
    image: apacherocketmq/rocketmq-dashboard:2.1.0
    container_name: rmqdashboard
    profiles:
      - dashboard
    restart: unless-stopped
    environment:
      JAVA_OPTS: >-
        -Dserver.port=8082
        -Drocketmq.namesrv.addr=namesrv:9876
        -Dcom.rocketmq.sendMessageWithVIPChannel=false
    depends_on:
      - namesrv
      - broker
    ports:
      - "127.0.0.1:8082:8082"
    networks:
      - rocketmq
    logging:
      driver: json-file
      options:
        max-size: "20m"
        max-file: "5"

  backup:
    image: apache/rocketmq:5.3.2
    profiles:
      - maintenance
    user: "0:0"
    volumes:
      - broker-store:/source:ro
      - ./backups:/backup
    entrypoint:
      - sh
      - -c
    command:
      - "true"

  restore:
    image: apache/rocketmq:5.3.2
    profiles:
      - maintenance
    user: "0:0"
    volumes:
      - broker-store-restored:/target
      - ./backups:/backup:ro
    entrypoint:
      - sh
      - -c
    command:
      - "true"

networks:
  rocketmq:
    name: rocketmq
    driver: bridge

volumes:
  namesrv-logs:
    name: rocketmq-namesrv-logs
  broker-logs:
    name: rocketmq-broker-logs
  broker-store:
    name: rocketmq-broker-store
  broker-store-restored:
    name: rocketmq-broker-store-restored

Compose 使用固定卷名,部署目录改名后不会悄悄创建另一组空卷。官方镜像以 UID/GID 3000:3000rocketmq 用户运行;命名卷由 Docker 管理,可以避免宿主机绑定目录常见的属主不匹配问题。

所有宿主机端口默认绑定 127.0.0.1。应用也在 Docker 中运行时,优先把应用加入 rocketmq 网络,并使用 proxy:8081,无需把任何 RocketMQ 端口暴露到宿主机。

校验并启动

bash
cd "$HOME/apps/rocketmq"
docker compose config
docker compose pull
docker compose up -d
docker compose ps

docker compose config 应输出规范化配置且没有错误。三个容器启动存在先后窗口,depends_on 只控制启动顺序,不表示依赖已经就绪;如果 Proxy 第一次启动失败,restart: on-failure 会在 NameServer 和 Broker 可用后重试。

查看有界日志:

bash
docker compose logs --tail=100 namesrv
docker compose logs --tail=100 broker
docker compose logs --tail=100 proxy

日志中不应持续出现连接 NameServer 失败、Broker 注册失败、存储目录不可写或反复重启。

可选:启动 RocketMQ Dashboard

Dashboard 不参与生产和消费链路,因此默认不会随基础服务启动。需要图形化查看集群、Topic、Consumer 和消息时,启用 dashboard profile:

bash
docker compose --profile dashboard up -d dashboard
docker compose ps
docker compose logs --tail=100 dashboard

浏览器访问 http://127.0.0.1:8082。本文固定使用 apacherocketmq/rocketmq-dashboard:2.1.0,并显式设置 Dashboard 容器监听 8082,避免不同历史文档中的 80808082 示例产生歧义。

Dashboard 使用经典管理客户端访问 namesrv:9876 和 Broker。配置中的 sendMessageWithVIPChannel=false 让 Dashboard 使用 Broker 主通信端口 10911,不依赖 10909 VIP 通道。Dashboard 页面包含创建 Topic、修改配置、重置消费位点和发送消息等管理操作,只应在本机或受控管理网络中开放;不要把无额外防护的管理界面直接发布到公网。

不再需要时只停止可选组件,不影响 NameServer、Broker 和 Proxy:

bash
docker compose stop dashboard
docker compose rm -f dashboard

创建主题

RocketMQ 客户端发送消息前先创建主题。下面的命令在 Broker 容器中调用官方 mqadmin

bash
docker compose exec broker \
  sh mqadmin updatetopic \
  -n namesrv:9876 \
  -c DefaultCluster \
  -t DemoTopic

成功时命令会返回 create topic to ... success。随后确认主题已经注册:

bash
docker compose exec broker \
  sh mqadmin topicList -n namesrv:9876 | grep '^DemoTopic$'

生产环境不要依赖自动创建主题。预先创建主题并明确读写队列数、权限和消息类型,才能让容量与权限变更进入受控流程。

常用 mqadmin 查询命令

mqadmin 可以直接查询路由和运行状态,适合脚本化验收与故障排查:

bash
# 列出集群及 Broker 注册信息
docker compose exec broker \
  sh mqadmin clusterList -n namesrv:9876

# 列出 Topic
docker compose exec broker \
  sh mqadmin topicList -n namesrv:9876

# 查看指定 Topic 的队列状态
docker compose exec broker \
  sh mqadmin topicStatus -n namesrv:9876 -t DemoTopic

# 查看 Consumer Group 的消费进度
docker compose exec broker \
  sh mqadmin consumerProgress -n namesrv:9876 -g YOUR_CONSUMER_GROUP

YOUR_CONSUMER_GROUP 替换为实际消费者组。修改类命令应先确认目标集群、Topic、Broker 和影响范围;日常查询优先使用上述只读命令。

客户端接入

宿主机应用

RocketMQ 5.x Java 客户端通过 Proxy 接入时,把 endpoint 配置为:

text
127.0.0.1:8081

Maven 依赖使用独立演进的 gRPC 客户端:

xml
<dependency>
  <groupId>org.apache.rocketmq</groupId>
  <artifactId>rocketmq-client-java</artifactId>
  <version>${rocketmq-client-java-version}</version>
</dependency>

Java 客户端不再配置 name-server,而是在 ClientConfiguration 中设置 Proxy endpoint:

java
ClientServiceProvider provider = ClientServiceProvider.loadService();

ClientConfiguration configuration = ClientConfiguration.newBuilder()
    .setEndpoints("127.0.0.1:8081")
    .build();

Producer producer = provider.newProducerBuilder()
    .setClientConfiguration(configuration)
    .setTopics("DemoTopic")
    .build();

${rocketmq-client-java-version} 应替换为项目实际选定并完成兼容验证的 SDK 版本。把经典客户端的 NameServer 地址改成 8081 不能完成迁移;采用 gRPC 路径需要同时更换客户端依赖和初始化 API。

生产者与消费者都应使用已经创建的 DemoTopic。生产者还需要在发送前声明目标主题;消费者需要设置独立、稳定的 consumer group,并为订阅关系配置 Tag 或 SQL 过滤表达式。

同一 Docker 网络中的应用

把应用服务加入已存在的 rocketmq 网络:

yaml
services:
  app:
    image: your-application:version
    networks:
      - rocketmq

networks:
  rocketmq:
    external: true
    name: rocketmq

应用 endpoint 使用:

text
proxy:8081

容器内的 localhost 指向应用容器自身,不能写成 localhost:8081。如果应用与 RocketMQ 位于不同主机,应在可信内网、访问控制和 TLS 方案完成后再开放 Proxy 端口,并把 endpoint 改为可路由的域名或内网地址。

经典 Remoting 客户端

经典客户端先访问 NameServer,再连接 Broker 返回的地址。跨主机访问时通常需要在自定义 broker.conf 中配置 brokerIP1,并开放 98761090910911 和按需使用的端口。错误的 brokerIP1 会导致客户端能查询路由却无法连接 Broker。

本文不提供一个固定 brokerIP1,因为这个值必须是目标网络中真实可达的主机地址。需要经典客户端或公网跨主机访问时,应先完成网络、认证、TLS 和防火墙设计,再按官方 Broker 配置文档挂载版本匹配的 broker.conf

验证部署结果

下面的检查需要在目标主机执行。当前文档只完成静态校验,预期结果是验收标准,不是运行实测记录。

容器状态

bash
docker compose ps
docker inspect -f '{{.Name}} restart={{.RestartCount}} state={{.State.Status}}' \
  rmqnamesrv rmqbroker rmqproxy

三个容器都应为 running,重启次数不应持续增加。

集群注册

bash
docker compose exec broker \
  sh mqadmin clusterList -n namesrv:9876

输出中应出现 DefaultCluster、Broker 名称、Broker 地址和版本。只有容器在运行但 clusterList 没有 Broker,说明注册链路尚未通过。

主题路由

bash
docker compose exec broker \
  sh mqadmin topicRoute -n namesrv:9876 -t DemoTopic

输出应包含 DemoTopic 的队列与 Broker 路由。主题不存在时重新执行创建命令,并检查 Broker 日志。

Proxy 监听与日志

bash
docker compose exec proxy sh -c 'nc -z 127.0.0.1 8081'
docker compose logs --tail=100 proxy

端口检查应以退出码 0 结束,日志不应持续出现连接 NameServer 或 Broker 失败。TCP 监听只证明 Proxy 已接收连接,完整验收仍需目标语言客户端完成一次生产和消费。

生产与消费

使用业务所采用的官方 RocketMQ 5.x SDK,按以下顺序验收:

  1. endpoint 指向 127.0.0.1:8081 或 Docker 网络内的 proxy:8081
  2. Producer 向 DemoTopic 发送带唯一 key 的测试消息,并记录返回的 message ID。
  3. Consumer 使用专用测试 group 订阅 DemoTopic,确认收到同一 key 和消息体。
  4. Consumer 成功处理后返回成功状态,再检查消费进度没有持续堆积。

客户端版本、重试、超时、消费并发和消息类型应按所用 SDK 的版本文档设置。不要用 curl 模拟 RocketMQ gRPC 协议,也不要把 TCP 端口可达误认为消息收发已经通过。

持久化

先确认数据卷存在:

bash
docker volume inspect rocketmq-broker-store

完成一轮生产与消费后重建 Broker 和 Proxy:

bash
docker compose up -d --force-recreate broker proxy
docker compose exec broker \
  sh mqadmin topicRoute -n namesrv:9876 -t DemoTopic

主题路由应恢复。随后使用新的测试 consumer group 读取重建前发送且仍在保留期内的消息,才能证明消息存储跨容器重建保留。只检查卷存在不能证明数据可恢复。

日常运维

bash
docker compose ps
docker compose logs --tail=200 namesrv broker proxy
docker compose restart proxy
docker compose restart broker
docker stats rmqnamesrv rmqbroker rmqproxy

Broker 重启会中断单节点消息服务。执行 restart broker 前先确认客户端重试策略、业务低峰窗口和消息积压情况。

查看主题与消费进度:

bash
docker compose exec broker \
  sh mqadmin topicList -n namesrv:9876

docker compose exec broker \
  sh mqadmin consumerProgress -n namesrv:9876 -g YOUR_CONSUMER_GROUP

YOUR_CONSUMER_GROUP 替换为实际消费者组。持续增长的 diff 表示消费落后,需要结合消费者日志、处理耗时、失败重试和 Broker 资源判断原因。

备份与恢复

RocketMQ 的关键单机数据位于 rocketmq-broker-store。一致性备份需要先停止写入并停止 Broker;仅复制正在写入的 CommitLog 和 ConsumeQueue 可能得到不可用的时间点。

创建备份

先停止生产者,等待消费者处理完目标范围的消息,再停止 Proxy 和 Broker:

bash
cd "$HOME/apps/rocketmq"
mkdir -p backups
docker compose stop proxy broker

使用 Compose 的 maintenance profile 启动一次性 backup 容器。备份容器使用同版本官方镜像,只读挂载当前数据卷,并把归档写入部署目录下的 backups/

bash
docker compose --profile maintenance run --rm backup \
  'tar -czf /backup/rocketmq-store-$(date +%F-%H%M%S).tar.gz -C /source .'

同时保存 Compose 配置,并检查归档可读:

bash
cp compose.yaml "backups/compose-$(date +%F-%H%M%S).yaml"
tar -tzf "$(ls -1t backups/rocketmq-store-*.tar.gz | head -1)" | head
docker compose up -d broker proxy

备份文件应复制到另一台主机或对象存储,并设置访问控制、校验和和保留策略。与运行卷位于同一磁盘的归档不能抵御主机或磁盘故障。

恢复到新卷

恢复会覆盖目标时间点后的数据。先停止生产者并确认选择了正确归档:

bash
cd "$HOME/apps/rocketmq"
docker compose down
docker volume create rocketmq-broker-store-restored

把归档恢复到新卷,避免直接破坏原卷:

bash
BACKUP_FILE="$(ls -1t backups/rocketmq-store-*.tar.gz | head -1)"

docker compose --profile maintenance run --rm restore \
  "tar -xzf /backup/$(basename "$BACKUP_FILE") -C /target && chown -R 3000:3000 /target"

临时把 compose.yamlbroker-store 卷的 name 改为 rocketmq-broker-store-restored,再启动并执行 clusterListtopicRoute 和真实消息消费验收。恢复确认前保留原卷;不要运行 docker compose down -v 或删除原卷。

升级与回滚

RocketMQ 5.5.1 已发布,但本文的 5.3.2 配置不自动代表 5.5.1 的镜像、参数和存储升级已经兼容。升级前必须完成以下检查:

  1. 阅读目标版本及中间版本发布说明,确认 Broker、Proxy、客户端和存储格式的兼容要求。
  2. 确认 apache/rocketmq:<目标版本> 镜像标签存在,并核对目标 CPU 架构。
  3. 停止写入,按上一节创建离线备份,并在独立主机或独立卷完成恢复演练。
  4. 在测试环境使用生产数据副本验证 NameServer 注册、主题路由、生产、消费、重试和积压查询。
  5. 先升级客户端兼容范围,再按官方建议安排服务端升级;单节点部署没有滚动升级能力。

升级时先记录当前镜像和卷:

bash
docker compose images
docker volume inspect rocketmq-broker-store

只有版本验证完成后,才修改三个服务的镜像标签并执行:

bash
docker compose config
docker compose pull
docker compose up -d
docker compose ps

回滚不仅是把镜像标签改回 5.3.2。如果新版本已经改写存储,旧版本可能无法读取;应停止新版本,把 Compose 恢复到旧标签,并切换到升级前备份恢复出的新卷。保留升级前原卷和备份,直到业务验收和观察期结束。

安全边界

  • 默认端口只绑定 127.0.0.1。远程应用优先通过 VPN、可信内网、SSH 隧道或受控容器网络连接,不要直接把 NameServer、Broker 或 Proxy 暴露到公网。
  • 本文没有启用 RocketMQ ACL 或 TLS。需要跨主机、多租户或不可信网络时,应按目标版本官方安全文档配置认证、授权与传输加密,再开放网络端口。
  • rocketmq-broker-store 包含消息正文、主题与消费相关数据,备份按敏感业务数据管理。限制 Docker daemon、宿主机和备份存储的访问权限。
  • 不要在 Compose、Git 仓库、日志或截图中保存 AccessKey、SecretKey、业务消息内容或真实客户端凭据。
  • 单 Broker 没有副本冗余。需要生产高可用时,部署多 Broker 副本并验证故障切换、容量、监控和恢复目标;增加 restart 策略不能替代高可用。
  • Docker json-file 日志已经限制单文件大小,但 RocketMQ 自身日志位于命名卷,仍需监控卷使用量和设置符合业务要求的日志保留策略。

常见问题

Compose 中的端口映射都必须保留吗

不必须。容器内进程必须监听对应服务端口,但 Compose ports 只负责把容器端口发布到宿主机。NameServer、Broker、Proxy 和应用都在同一个 Docker 网络时,组件可以通过服务名和容器端口通信,宿主机映射可以全部删除。

RocketMQ 5.x 同时支持经典 Remoting 和新增的 gRPC 接入,不能只按服务端版本判断端口。先确认应用使用的客户端协议:

端口组件与用途4.x 及 5.x 经典 Remoting 客户端5.x gRPC 客户端什么时候可以不写 Compose ports
9876NameServer 路由查询应用必须能访问;代码通常只显式配置这个地址应用不直接访问,Proxy 必须在内部网络访问应用或 Proxy 与 NameServer 位于同一 Docker 网络时
10911Broker 主要 Remoting 通信应用必须能访问 NameServer 返回的 Broker 地址应用不直接访问,Proxy 必须在内部网络访问只使用 Proxy,或经典客户端与 Broker 位于同一 Docker 网络时
10909Broker VIP 通道只有启用 VIP channel 的客户端需要gRPC 路径不需要未启用 VIP channel,或只使用 gRPC Proxy 时
10912Broker 主从复制单 Broker 客户端不使用gRPC 客户端不使用单 Broker 部署可以不发布;多副本时应只在 Broker 间的可信网络开放
8080Proxy Remoting 接入只有明确让 Remoting 客户端通过 Proxy 接入时需要纯 gRPC 客户端不使用经典客户端直连 NameServer/Broker,或只使用 8081 gRPC 时
8081Proxy gRPC endpoint经典客户端不使用应用必须能访问gRPC 应用与 Proxy 位于同一 Docker 网络,使用 proxy:8081

常见部署可以收敛为三种端口方案:

  1. RocketMQ 4.x 或 5.x 经典客户端在 Docker 外部:至少保证 987610911 可达;启用 VIP channel 时还要保证 10909 可达,并把 brokerIP1 设置为客户端可路由的地址。10912 不应作为客户端端口开放。
  2. RocketMQ 5.x gRPC 客户端在 Docker 外部:通常只发布 Proxy 8081。NameServer 和 Broker 端口保留在内部网络;不使用 Proxy Remoting 时可以删除 8080 映射。
  3. 应用与 RocketMQ 位于同一 Docker 网络:可以删除全部宿主机 ports。经典客户端使用 namesrv:9876 并直连内部 Broker,gRPC 客户端使用 proxy:8081

本文 Compose 把全部端口绑定到 127.0.0.1,目的是同时支持本机诊断、经典客户端和 gRPC 客户端,不代表每个端口都是业务必选项。修改后先执行 docker compose config,再根据实际客户端完成一次生产和消费;只检查端口监听不能证明消息链路可用。

Dashboard 的 8082 只用于可选 Web 管理界面。未启用 dashboard profile 时无需发布 8082;启用后如果只在宿主机访问,保留 127.0.0.1:8082:8082 即可。Dashboard 不会让 Producer 或 Consumer 少开放任何业务协议端口。

Proxy 持续重启

先看三个组件的最近日志:

bash
docker compose logs --tail=200 namesrv broker proxy

如果 Proxy 报告 NameServer 或 Broker 不可达,确认 NAMESRV_ADDR=namesrv:9876 没有改成宿主机地址,并用 clusterList 验证 Broker 已注册。首次启动存在就绪时间差,短暂重试可以接受;持续重启表示依赖或配置仍有问题。

客户端能连接 Proxy 但发送失败

确认 endpoint 是 127.0.0.1:8081 或 Docker 网络内的 proxy:8081,主题已经通过 mqadmin updatetopic 创建,客户端声明的主题名与 DemoTopic 完全一致。继续检查 Proxy 和 Broker 日志中的主题不存在、权限、超时或消息类型错误。

经典客户端能查询路由但连不上 Broker

NameServer 返回的 Broker 地址对客户端不可达。检查 mqadmin topicRoute 输出中的 Broker 地址、Docker 端口映射、防火墙和 brokerIP1。跨主机经典客户端不能照搬本文的回环绑定;先完成内网地址与安全配置,再修改监听范围。

Broker 报存储目录不可写

本文使用 Docker 命名卷,正常情况下 Docker 会为容器准备卷。若改成宿主机绑定目录,官方镜像使用 UID/GID 3000:3000,目录属主不匹配会导致写入失败。停止容器,确认目标路径无误后再调整该部署目录的属主;不要对宽泛目录执行递归 chmod 777

磁盘持续增长

先确认 Docker 卷所在文件系统、Broker 日志和消息保留配置:

bash
docker system df -v
docker compose logs --tail=200 broker
docker compose exec broker \
  sh mqadmin getBrokerConfig -n namesrv:9876 -b rmqbroker:10911

消息堆积、保留时间、消费失败和 RocketMQ 自身日志都会占用空间。不要在运行中直接删除卷内 CommitLog、ConsumeQueue 或索引文件;先停止写入、完成备份,再按目标版本官方运维文档处理保留与清理。

Docker Hub 拉取失败

先保留固定标签并检查网络、DNS、代理和 Docker daemon 的 registry 配置:

bash
docker pull apache/rocketmq:5.3.2

不要把镜像临时改成 latest,也不要使用来源不明的第三方镜像。离线环境应在联网主机拉取固定标签,使用 docker save 导出,并在目标主机用 docker load 导入;传输后记录并核对镜像 ID 或摘要。

总结

这套 Compose 提供一个可持久化的 RocketMQ 单节点基线:NameServer 管理路由,Broker 保存消息,Proxy 为 5.x 客户端提供统一入口。完成部署后,至少执行 clusterList、主题路由、真实生产与消费、容器重建后的消息读取以及备份恢复演练;只有这些检查通过,才能把配置从开发验证推进到受控内网服务。生产高可用仍需要多副本集群、认证与 TLS、监控告警、容量规划和跨主机恢复方案。

参考资料

全部公开文章由同一个站点构建和发布。