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 端口 | 9876 | 9000 | 直接 docker -p 9000:9876 映射即可。 |
Broker 监听端口 | 10911 | 9050 | 修改 listenPort=9050 |
Broker 管理端口 | 10909 | 9048 | 这个 9048 的值必须根据 listenPort 计算而来,是固定的。即 ([Broker 管理端口] = listenPort -2) |
Dashboard | 8080 | 9070 | 直接 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
- 8080(Dashboard 需要开启):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