Skip to content

Docker 安装 RocketMQ

Docker 安装适合本地学习、快速验证 API、搭建临时测试环境。它解决的是“先跑起来理解组件关系”的问题,不适合作为生产部署方式直接照搬。生产环境还要考虑磁盘挂载、Broker 主从、监控、限流、日志保留和数据备份。

为什么 Docker 安装要同时关注 NameServer、Broker 和 Proxy

RocketMQ 不是单个进程就能完整工作的系统。最少要理解三个角色:

mermaid
flowchart TD
    A["Producer / Consumer"] --> B["Proxy<br/>5.x 客户端接入层"]
    A --> C["NameServer<br/>路由发现"]
    B --> C
    B --> D["Broker<br/>消息存储和投递"]
    D --> C
组件作用如果没有或配置错会怎样
NameServer保存 Topic、Broker 路由信息客户端找不到 Broker,发送和消费都失败
Broker存储消息、维护队列、投递消息消息没有地方保存,Topic 无法真正工作
ProxyRocketMQ 5.x 推荐接入层,提供 gRPC/remoting 接入新客户端连接地址写错时会连不上或超时

Docker 网络的核心是让容器之间能通过容器名互相访问。例如 Broker 配置 NAMESRV_ADDR=rmqnamesrv:9876,这里的 rmqnamesrv 是同一个 Docker network 中的容器名,不是宿主机地址。

镜像拉取

shell
docker pull apache/rocketmq:5.2.0

由于dockerHub被限制拉取会失败,可以使用自建镜像仓库。我使用的是阿里云的镜像云服务(个人版)并配合github的workflow来拉取推送镜像。

以下是我的镜像仓库地址(不保证最新,个人什么时候使用到才会更新。)

推荐自己搭建毕竟也免费。

shell
  docker pull registry.cn-hangzhou.aliyuncs.com/lautrans/rocketmq

创建容器共享网络

shell
docker network create rocketmq

为什么要创建共享网络:如果不创建网络,容器之间只能靠默认桥接网络和 IP 通信,IP 变化后配置容易失效。共享网络可以让 Broker 直接用 rmqnamesrv:9876 找到 NameServer。

启动nameserver

shell
# 启动 NameServer
docker run -d --name rmqnamesrv -p 9876:9876 --network [containerName] [imageName] sh mqnamesrv
# DEMO
docker run -d --name rmqnamesrv -p 9876:9876 --network rocketmq  rocketmq  sh mqnamesrv

验证 NameServer 是否启动成功

shell
docker logs -f rmqnamesrv

启动 Broker+Proxy

配置 Broker 的IP地址

shell
echo "brokerIP1=127.0.0.1" > broker.conf

brokerIP1=127.0.0.1是官网配置的默认值,实际访问的时候可能存在问题。

解决方式: 将brokerIP1修改为实际(虚拟机或服务器)IP 地址。

启动 Broker 和 Proxy

shell
docker run -d \
--name rmqbroker \
--network rocketmq \
-p 10912:10912 -p 10911:10911 -p 10909:10909 \
-p 8080:8080 -p 8081:8081 \
-e "NAMESRV_ADDR=rmqnamesrv:9876" \
-v ./broker.conf:/home/rocketmq/rocketmq-5.2.0/conf/broker.conf \
rocketmq sh mqbroker --enable-proxy \
-c /home/rocketmq/rocketmq-5.2.0/conf/broker.conf

验证 Broker 是否启动成功

shell
docker exec -it rmqbroker bash -c "tail -n 10 /home/rocketmq/logs/rocketmqlogs/proxy.log"

启动流程原理

mermaid
flowchart TD
    A["创建 docker network"] --> B["启动 NameServer"]
    B --> C["Broker 读取 broker.conf"]
    C --> D["Broker 向 NameServer 注册路由"]
    D --> E["Proxy 随 Broker 启动"]
    E --> F["客户端通过 endpoints 连接 Proxy"]
    F --> G["发送 / 消费消息"]

理解这个流程后,排查会清楚很多:客户端连不上不一定是 Broker 没启动,也可能是 Proxy 端口没映射;生产者发送失败不一定是代码问题,也可能是 Broker 注册到 NameServer 的地址是容器内地址,宿主机访问不到。

常见风险和排查

现象常见原因排查命令
客户端连接超时brokerIP1 写成 127.0.0.1,外部机器无法访问docker logs rmqbroker、检查 broker.conf
Broker 启动但客户端找不到 TopicBroker 没注册到 NameServer 或 NameServer 地址错`docker exec rmqbroker env
端口冲突宿主机已有服务占用 8080/8081/10911`netstat -ano
容器重启后消息没了没有挂载数据目录,容器删除导致数据丢失/home/rocketmq/store 配置 volume
5.x 客户端连不上endpoints 应该连 Proxy 端口,不是 NameServer 端口检查客户端 setEndpoints 是否写 8081/9081

最小验证 Demo

先确认容器状态:

shell
docker ps
docker logs rmqnamesrv --tail 50
docker logs rmqbroker --tail 50

再进入 Broker 容器查看日志:

shell
docker exec -it rmqbroker bash
tail -f /home/rocketmq/logs/rocketmqlogs/proxy.log

如果使用 RocketMQ 5.x Java Client,endpoints 应该指向 Proxy 暴露出来的端口,例如:

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

学习环境可以先用单 NameServer、单 Broker。等理解消息发送、消费、重试、死信和顺序消息后,再学习生产集群部署。