您现在的位置是:首页 >学无止境 >Docker Compose部署RocketMQ和控制中心网站首页学无止境
Docker Compose部署RocketMQ和控制中心
最近单位有个应用需要上
RocketMQ
,考虑到资源不是特别充足且该应用重要性分级不高,打算采用Docker Compose
方式单机部署。让我们一起来看看该过程中有哪些坑💥💥
创建RocketMQ相关目录和文件
创建持久化日志和数据目录
#namesrv的日志目录
mkdir -p /data/rocketmq/namesrv/logs
#broker的日志、数据、配置文件目录
mkdir -p /data/rocketmq/broker/{conf,logs,store}
创建broker.conf配置文件
brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH
# IP设置为主机IP
brokerIP1=192.168.124.80
autoCreateTopicEnable=true
autoCreateSubscriptionGroup=true
waitTimeMillsInSendQueue=1000
#设置namesrv地址,建议不做修改
namesrvAddr=rmqnamesrv:9876
traceTopicEnable=true
编排docker
编排docker-compose.yaml
version: '3.8'
services:
rmqnamesrv:
image: apache/rocketmq:4.7.1
container_name: rmqnamesrv
ports:
- 9876:9876
restart: always
volumes:
- /data/rocketmq/namesrv/logs:/home/rocketmq/logs
environment:
JAVA_OPT: -server -Xms256m -Xmx512m -Xmn128m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m
command: ["sh","mqnamesrv"]
#看环境需求,是使用默认网络模式还是host模式
#network_mode: "host"
broker:
image: apache/rocketmq:4.7.1
container_name: rmqbroker
ports:
- 10909:10909
- 10911:10911
- 10912:10912
restart: always
volumes:
- /data/rocketmq/broker/logs:/home/rocketmq/logs
- /data/rocketmq/broker/store:/home/rocketmq/store
- /data/rocketmq/broker/conf/broker.conf:/home/rocketmq/rocketmq-4.7.1/conf/broker.conf
depends_on:
- 'rmqnamesrv'
environment:
JAVA_OPT: -server -Xms256m -Xmx512m -Xmn128m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m
command: ["sh","mqbroker","-c","/home/rocketmq/rocketmq-4.7.1/conf/broker.conf"]
#network_mode: "host"
rmqdashboard:
image: apacherocketmq/rocketmq-dashboard:latest
container_name: rocketmq-dashboard
ports:
- 8081:8080
restart: always
depends_on:
- 'rmqnamesrv'
environment:
- JAVA_OPTS= -Xms256M -Xms512M -Xmn128M -Drocketmq.namesrv.addr=rmqnamesrv:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false
#network_mode: "host"
如果使用了host网络模式,
broker.conf
配置文件的namesrvAddr=rmqnamesrv:9876
可以设置为namesrvAddr=主机IP:9876
启动RocketMQ
docker compose up
docker compose分为V1和V2版本,独立安装的V1和V2版本使用
docker-compose
方式启动,插件安装的V2版本使用’docker compose’方式启动
报错
好了,现在坑💥来了
可以看到namesrv启动成功,但是broker异常退出,并且没有任何日志,导致后面有依赖关系的dashboard连接broker也出现异常。
落坑
docker compose启动指定container
因为该docker-compose.yaml文件有3个container且有依赖关系,为方便排错,暂时去掉依赖关系,并只启动broker container
version: '3.8'
services:
rmqnamesrv:
...
broker:
...
# depends_on:
# - 'rmqnamesrv'
environment:
JAVA_OPT: -server -Xms256m -Xmx512m -Xmn128m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m
command: ["sh","mqbroker","-c","/home/rocketmq/rocketmq-4.7.1/conf/broker.conf"]
rmqdashboard:
...
启动后错误同上。
docker compose up broker
直接使用docker run方式启动
docker run --name rmqbroker --restart always -p 10909:10909 -p 10911:10911 -p 10912:10912 -e "JAVA_OPT=-server -Xms256m -Xmx512m -Xmn128m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m" -v /data/rocketmq/broker/logs:/home/rocketmq/logs -v /data/rocketmq/broker/store:/home/rocketmq/store -v /data/rocketmq/broker/conf/broker.conf:/home/rocketmq/rocketmq-4.7.1/conf/broker.conf apache/rocketmq:4.7.1 sh mqbroker -c /home/rocketmq/rocketmq-4.7.1/conf/broker.conf
果然,还是一样的错误且没有日志。在求助搜索引擎后也没有找到合适的解决办法。
上大招💘,求助deepseek
!
- 配置 Docker Compose 日志记录
- 强制显示实时日志
- 捕获容器退出时的状态
- 启用 Docker 调试日志
- 手动调试容器启动过程
逐一按照最强AI
的思路,在最后的手动调试启动过程中发现了端倪(填坑耗时6️⃣小时)
爬坑
- 启动容器,但不启动broker
docker run -it
--name rmqbroker-debug
-v /data/rocketmq/broker/logs:/home/rocketmq/logs
-v /data/rocketmq/broker/store:/home/rocketmq/store
-v /data/rocketmq/broker/conf/broker.conf:/home/rocketmq/rocketmq-4.7.1/conf/broker.conf
apache/rocketmq:4.7.1
sh -c "tail -f /dev/null"
这里我们在dockr启动后,不执行启动mqbroker的命令,只保持容器运行
成功启动,没有之前的异常退出和反复重启等故障,见到曙光啦🌥️!从目前来看,应该是之前执行启动mqbroker时出错了
- 进入容器手动执行命令
#进入容器
docker exec -it rmqbroker-debug bash
# 手动执行 Broker 启动命令
sh mqbroker -c /home/rocketmq/rocketmq-4.7.1/conf/broker.conf
可以正常执行但是无任何输出,几个意思?检查日志吧
[root@docker logs]# pwd
/data/rocketmq/broker/logs
[root@docker logs]# ls -l
total 0
#容器内
[rocketmq@ff756bdbe93e logs]$ pwd
/home/rocketmq/logs
[rocketmq@ff756bdbe93e logs]$ ls -l
total 0
明明挂载了本地路径,为什么容器内外都无法生成日志呢,权限问题❓
[rocketmq@ff756bdbe93e ~]$ ls -lh
total 0
drwxr-xr-x 2 root root 6 Feb 8 06:43 logs
drwxr-xr-x 1 rocketmq rocketmq 17 Jul 31 2021 rocketmq-4.7.1
drwxr-xr-x 2 root root 6 Feb 8 06:43 store
[rocketmq@ff756bdbe93e conf]$ pwd
/home/rocketmq/rocketmq-4.7.1/conf
[rocketmq@ff756bdbe93e conf]$ ls -l
total 36
drwxr-xr-x 1 rocketmq rocketmq 118 Jun 2 2020 2m-2s-async
drwxr-xr-x 1 rocketmq rocketmq 118 Jun 2 2020 2m-2s-sync
drwxr-xr-x 1 rocketmq rocketmq 91 Jun 2 2020 2m-noslave
-rw-r--r-- 1 root root 361 Jan 24 01:47 broker.conf
drwxr-xr-x 1 rocketmq rocketmq 72 Jun 2 2020 dledger
-rw-r--r-- 1 rocketmq rocketmq 14978 Jun 2 2020 logback_broker.xml
-rw-r--r-- 1 rocketmq rocketmq 3836 Jun 2 2020 logback_namesrv.xml
-rw-r--r-- 1 rocketmq rocketmq 3761 Jun 2 2020 logback_tools.xml
-rw-r--r-- 1 rocketmq rocketmq 1305 Jun 2 2020 plain_acl.yml
-rw-r--r-- 1 rocketmq rocketmq 834 Jun 2 2020 tools.yml
rocketmq的家目录是rocketmq属主/组的,并且配置目录下除了挂载的broker.conf
其他文件也都是rocketmq属主/组。
已经很明确,就是权限问题导致的之前启动异常退出,以及手动调试时无报错情况。
3. 查看dockerfile确认权限问题
完整文件请看这里
...
#添加用户和组
7 ARG uid=3000
8 ARG gid=3000
9 |4 gid=3000 group=rocketmq uid=3000 user=rocketmq /bin/sh -c groupadd -g ${gid} ${group} && useradd -u ${uid} -g ${gid} -m -s /bin/bash ${user}
...
#设置工作目录
12 ENV ROCKETMQ_HOME=/home/rocketmq/rocketmq-4.7.1
13 WORKDIR /home/rocketmq/rocketmq-4.7.1
...
#更改家目录的属主/组
16 |5 gid=3000 group=rocketmq uid=3000 user=rocketmq version=4.7.1 /bin/sh -c chown -R ${uid}:${gid} ${ROCKETMQ_HOME}
...
真相大白❗❗❗官方镜像设置了容器内运行用户为rocketmq
,并修改了相关目录的权限。
修正错误
修改权限
[root@docker data]# chown -R 3000:3000 rocketmq/
[root@docker data]# ls -lh
total 12K
drwxr-xr-x 4 3000 3000 61 Feb 6 16:47 rocketmq
启动最初完整的docker compose
docker compose up
成功启动
查看dashboard
测试功能
写个python测试
import json
from rocketmq.client import Producer, Message
producer = Producer('testGroup')
producer.set_name_server_address('192.168.124.80:9876')
producer.start()
msg = Message('testTopic')
msg_body = {"id":"test_id","name":"test_name","message":"test_message"}
ss = json.dumps(msg_body).encode('utf-8')
msg.set_body(ss)
producer.send_sync(msg)
producer.shutdown()
~
查看dashboard