Docker 安装 RocketMQ
Docker 安装适合本地学习、快速验证 API、搭建临时测试环境。它解决的是“先跑起来理解组件关系”的问题,不适合作为生产部署方式直接照搬。生产环境还要考虑磁盘挂载、Broker 主从、监控、限流、日志保留和数据备份。
为什么 Docker 安装要同时关注 NameServer、Broker 和 Proxy
RocketMQ 不是单个进程就能完整工作的系统。最少要理解三个角色:
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 无法真正工作 |
| Proxy | RocketMQ 5.x 推荐接入层,提供 gRPC/remoting 接入 | 新客户端连接地址写错时会连不上或超时 |
Docker 网络的核心是让容器之间能通过容器名互相访问。例如 Broker 配置 NAMESRV_ADDR=rmqnamesrv:9876,这里的 rmqnamesrv 是同一个 Docker network 中的容器名,不是宿主机地址。
镜像拉取
docker pull apache/rocketmq:5.2.0由于dockerHub被限制拉取会失败,可以使用自建镜像仓库。我使用的是阿里云的镜像云服务(个人版)并配合github的workflow来拉取推送镜像。
以下是我的镜像仓库地址(不保证最新,个人什么时候使用到才会更新。)
推荐自己搭建毕竟也免费。
shelldocker pull registry.cn-hangzhou.aliyuncs.com/lautrans/rocketmq
创建容器共享网络
docker network create rocketmq为什么要创建共享网络:如果不创建网络,容器之间只能靠默认桥接网络和 IP 通信,IP 变化后配置容易失效。共享网络可以让 Broker 直接用 rmqnamesrv:9876 找到 NameServer。
启动nameserver
# 启动 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 是否启动成功
docker logs -f rmqnamesrv启动 Broker+Proxy
配置 Broker 的IP地址
echo "brokerIP1=127.0.0.1" > broker.confbrokerIP1=127.0.0.1是官网配置的默认值,实际访问的时候可能存在问题。
解决方式: 将brokerIP1修改为实际(虚拟机或服务器)IP 地址。
启动 Broker 和 Proxy
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 是否启动成功
docker exec -it rmqbroker bash -c "tail -n 10 /home/rocketmq/logs/rocketmqlogs/proxy.log"启动流程原理
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 启动但客户端找不到 Topic | Broker 没注册到 NameServer 或 NameServer 地址错 | `docker exec rmqbroker env |
| 端口冲突 | 宿主机已有服务占用 8080/8081/10911 | `netstat -ano |
| 容器重启后消息没了 | 没有挂载数据目录,容器删除导致数据丢失 | 为 /home/rocketmq/store 配置 volume |
| 5.x 客户端连不上 | endpoints 应该连 Proxy 端口,不是 NameServer 端口 | 检查客户端 setEndpoints 是否写 8081/9081 |
最小验证 Demo
先确认容器状态:
docker ps
docker logs rmqnamesrv --tail 50
docker logs rmqbroker --tail 50再进入 Broker 容器查看日志:
docker exec -it rmqbroker bash
tail -f /home/rocketmq/logs/rocketmqlogs/proxy.log如果使用 RocketMQ 5.x Java Client,endpoints 应该指向 Proxy 暴露出来的端口,例如:
ClientConfiguration configuration = ClientConfiguration.newBuilder()
.setEndpoints("127.0.0.1:8081")
.build();学习环境可以先用单 NameServer、单 Broker。等理解消息发送、消费、重试、死信和顺序消息后,再学习生产集群部署。
