Skip to content

Docker 安装 RocketMQ

官方镜像:https://hub.docker.com/r/apache/rocketmq

官方 github docker 仓库:https://github.com/apache/rocketmq-docker

官方文档:Docker 部署 RocketMQ

部署文档1(官方文档)

部署 Name Server

shell
# 拉取镜像
docker pull apache/rocketmq:5.1.4

# 创建容器共享网络
# RocketMQ 中有多个服务,需要创建多个容器,创建 docker 网络便于容器间相互通信。
docker network create rocketmq

# 启动 NameServer
docker run -d --name rmqnamesrv --restart=always -p 9876:9876 --network rocketmq apache/rocketmq:5.1.4 sh mqnamesrv

# 验证 NameServer 是否启动成功
docker logs -f rmqnamesrv
# 可以看到 'The Name Server boot success..', 则表示 NameServer 已成功启动。

部署 Broker

shell
# 启动 Broker+Proxy
mkdir -p /opt/rocketmq/conf
cd /opt/rocketmq/conf


# 覆盖写入内容到 broker.conf
tee /opt/rocketmq/conf/broker.conf <<-'EOF'

brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH

# IP或域名
brokerIP1=192.168.188.146
# 自动创建 topic
autoCreateTopicEnable=true

EOF

cat broker.conf

# 启动 Broker 和 Proxy
docker run -d --restart=always \
--name rmqbroker \
--network rocketmq \
-p 10911:10911 -p 10912:10912 -p 10909:10909 \
-p 8081:8081 \
-e "NAMESRV_ADDR=rmqnamesrv:9876" \
-v /opt/rocketmq/conf/broker.conf:/home/rocketmq/rocketmq-5.1.4/conf/broker.conf \
apache/rocketmq:5.1.4 sh mqbroker --enable-proxy \
-c /home/rocketmq/rocketmq-5.1.4/conf/broker.conf

# 验证 Broker 是否启动成功
docker exec -it rmqbroker bash -c "tail -n 10 /home/rocketmq/logs/rocketmqlogs/proxy.log"
# 看到 'The broker boot success..', 则表示 Broker 已成功启动。

测试消息的发送和接收

shell
# 进入broker容器
$ docker exec -it rmqbroker bash

# cd /home/rocketmq/rocketmq-5.1.4/bin

# 查看当前的topic列表
./mqadmin topicList -n 192.168.188.146:9876

# 查看broker节点
./mqadmin clusterList -n 192.168.188.146:9876

# 创建topic: TopicTest(下面的测试可以不用创建,会自动创建)
./mqadmin updateTopic -n 192.168.188.146:9876 -b 192.168.188.146:10911 -c DefaultCluster -t TopicTest

# 查看当前的topic列表
./mqadmin topicList -n 192.168.188.146:9876


# 设置环境变量(linux)
export NAMESRV_ADDR="192.168.188.146:9876"

$ sh tools.sh org.apache.rocketmq.example.quickstart.Producer
# SendResult [sendStatus=SEND_OK, msgId= ...

$ sh tools.sh org.apache.rocketmq.example.quickstart.Consumer
# ConsumeMessageThread_%d Receive New Messages: [MessageExt...

rocketmq-dashboard (可选)

shell
docker run -d --name rocketmq-dashboard --restart=always \
-e "JAVA_OPTS=-Drocketmq.namesrv.addr=192.168.188.146:9876" \
-p 8080:8080 \
-t apacherocketmq/rocketmq-dashboard:1.0.0

# 访问 dashboard 地址: http://192.168.188.146:8080

Broker 启用 ACL 权限控制

更多权限配置参考官方文档:https://rocketmq.apache.org/zh/docs/bestPractice/03access/

shell
# 进入前面挂载的 broker.conf 文件目录
cd /opt/rocketmq/conf
# 追加以下内容
echo "aclEnable=true" >> broker.conf

cat broker.conf


# 从容器中复制 plain_acl.yml 到挂载目录,并修改内容
docker cp rmqbroker:/home/rocketmq/rocketmq-5.1.4/conf/plain_acl.yml /opt/rocketmq/conf/

cat plain_acl.yml

# 注意 admin: true 字段,这是管理员用户,可访问所有资源
# 注意 accessKey 和 secretKey 的值,spring boot 中需要配置
# 跟根据实际情况修改内容。

# 接下来,删除原来的容器
docker rm -f rmqbroker

# docker 启动参数增加如下挂载卷
-v /opt/rocketmq/conf/plain_acl.yml:/home/rocketmq/rocketmq-5.1.4/conf/plain_acl.yml

# 重新用 docker run 创建容器并启动即可

spring boot 配置 accessKey 和 secretKey

yaml
# 生产者
rocketmq:
  name-server: localhost:9876
  producer:
    group: group1
    accessKey: rocketmq2
    secretKey: 12345678

# 消费者
rocketmq:
  name-server: localhost:9876
  consumer:
    group: group1
    topic: string
    accessKey: rocketmq2
    secretKey: 12345678

这样,就可以成功发送和接收消息了。

启用 ACL 后,dashboard 同样需要增加认证配置。

shell
# docker 或 java -jar 启动参数需要增加如下参数:
-Drocketmq.config.accessKey=rocketmq2 -Drocketmq.config.secretKey=12345678

至此,结束。

部署文档2(docker 部署到外网,并修改端口)

有如下需求(至少需要开放以下端口):假如服务器主机域名为:aday.fun

服务名称默认端口外网端口备注
Name Server 端口98769000直接 docker -p 9000:9876 映射即可。
Broker 监听端口109119050修改 listenPort=9050
Broker 管理端口109099048这个 9048 的值必须根据 listenPort 计算而来,是固定的。即 ([Broker 管理端口] = listenPort -2)
Dashboard80809070直接 docker -p 9070:8080 映射即可。
shell
# 拉取镜像
docker pull apache/rocketmq:5.1.4

部署 Name Server:9000

shell
# 启动 NameServer
docker run -d --name rmqnamesrv --restart=always -p 9000:9876 apache/rocketmq:5.1.4 sh mqnamesrv

# 验证 NameServer 是否启动成功
docker logs -f rmqnamesrv
# 可以看到 'The Name Server boot success..', 则表示 NameServer 已成功启动。

# 此时,Name Server 的地址为:http://aday.fun:9000

部署 Broker:9050

shell
mkdir -p /opt/rocketmq/conf && cd /opt/rocketmq/conf

# 覆盖写入内容到 broker.conf
tee /opt/rocketmq/conf/broker.conf <<-'EOF'

brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH

# 外网IP或域名
brokerIP1=aday.fun
# 自动创建 topic
autoCreateTopicEnable=true
# 修改监听端口
listenPort=9050
# 启用 ACL
aclEnable=true

EOF

# 可以查看以下是否已经写入了这些内容
cat broker.conf

# 启动 Broker+Proxy(默认端口为:-p 10911:10911 -p 10909:10909,但是已经修改了 listenPort=9050,所以就需要改成 9050 和 9048 )

# 注意:修改 plain_acl.yml 和挂载卷参考前面【Broker 启用 ACL 权限控制】章节,可以先从容器中复制出来,然后删除容器,再修改后,再重新创建容器并启动。

docker run -d --restart=always \
--name rmqbroker \
-p 9050:9050 -p 9048:9048 \
-p 8081:8081 \
-e "NAMESRV_ADDR=aday.fun:9000" \
-v /opt/rocketmq/conf/broker.conf:/home/rocketmq/rocketmq-5.1.4/conf/broker.conf \
-v /opt/rocketmq/conf/plain_acl.yml:/home/rocketmq/rocketmq-5.1.4/conf/plain_acl.yml
apache/rocketmq:5.1.4 sh mqbroker --enable-proxy \
-c /home/rocketmq/rocketmq-5.1.4/conf/broker.conf

# 验证 Broker 是否启动成功
docker exec -it rmqbroker bash -c "tail -n 10 /home/rocketmq/logs/rocketmqlogs/proxy.log"
# 看到 'The broker boot success..', 则表示 Broker 已成功启动。

# 此时,Broker 的地址为:http://aday.fun:9050

测试消息的发送和接收

shell
# 进入broker容器
$ docker exec -it rmqbroker bash
# cd /home/rocketmq/rocketmq-5.1.4/bin

# 查看broker节点
./mqadmin clusterList -n aday.fun:9000

# 查看当前的topic列表
./mqadmin topicList -n aday.fun:9000

# 创建topic: TopicTest(下面的测试可以不用创建,会自动创建)
./mqadmin updateTopic -n aday.fun:9000 -b aday.fun:9050 -t TopicTest

# 再次查看当前的topic列表
./mqadmin topicList -n aday.fun:9000


# 设置环境变量(linux)
export NAMESRV_ADDR="aday.fun:9000"

$ sh tools.sh org.apache.rocketmq.example.quickstart.Producer
# SendResult [sendStatus=SEND_OK, msgId= ...

$ sh tools.sh org.apache.rocketmq.example.quickstart.Consumer
# ConsumeMessageThread_%d Receive New Messages: [MessageExt...

rocketmq-dashboard:9070 (可选)(启用登录)

shell
cd /opt/rocketmq/conf

# 执行命令,写入内容到 users.properties
tee /opt/rocketmq/conf/users.properties <<-'EOF'

# This file supports hot change, any change will be auto-reloaded without Dashboard restarting.
# Format: a user per line, username=password[,N] #N is optional, 0 (Normal User); 1 (Admin)

# Define Admin
admin=1qaz2wsx,1

# Define Users
#user1=1qaz2wsx

EOF

# 查看内容
$ cat users.properties

# 挂载卷并启动,指定容器固定 ip,开启 dashboard 登录参数,增加 Broker ACL 认证参数
docker run -d --name rocketmq-dashboard --restart=always \
--ulimit nofile=1024 \
-e "JAVA_OPTS=-Drocketmq.namesrv.addr=aday.fun:9000 -Dcom.rocketmq.sendMessageWithVIPChannel=false -Drocketmq.config.loginRequired=true -Drocketmq.config.accessKey=rocketmq2 -Drocketmq.config.secretKey=12345678 " \
-p 9070:8080 \
-v /opt/rocketmq/conf/users.properties:/tmp/rocketmq-console/data/users.properties \
-t apacherocketmq/rocketmq-dashboard:1.0.0

端口说明

  • 9876必须开启):NameServer 用于处理客户端的路由信息请求,Broker 的注册与发现。这是所有客户端和 Broker 必须知道的端口,用于初始化和定期更新路由信息。
  • 10911必须开启):Broker 默认的监听端口,用于处理客户端的消息发送、消息消费和获取消息等请求。
  • 10909必须开启):Broker管理端口。通常值=(Broker listenport - 2),即=(10911 - 2),默认不开启
  • 9878:Controller
  • 10912:Broker高可用(HA)端口:Broker 的高可用性服务端口,用于 Master Broker 与 Slave Broker 之间的数据复制。
  • 30912:主从同步端口
  • 8081:Proxy
  • 8080Dashboard 需要开启):Dashboard 页面访问端口

常见问题

unable to allocate file descriptor table - out of memoryAborted (core dumped)

因运存不足无法给进程分配更多的文件句柄数而异常退出。

shell
# 原运行指令
docker run  -d -p 8080:8080 docker-test:v1.0
# 改为(增加:--ulimit nofile=1024):
docker run --ulimit nofile=1024 -d -p 8080:8080 docker-test:v1.0