本文主要简单介绍rocketmq及使用docker安装rocketmq的方法。
rocketmq有两部分,nameserver和broker,nameserver用来维护broker的地址、向生产者、消费者推送broker的最新地址;broker用来存储、转发消息;也就是说,生产者首先要连接nameServer获取到broker的地址,然后将消息发送到broker,通过broker再将消息传递到消费者;
所以用docker安装rocketmq时,要启动两个容器,一个nameserver、一个broker,这两者要网络互通;
nameServer暴露的端口通常是9876;broker暴露的端口通常是10911,生产者就是往这个端口发送消息;消费者可能也是通过这个接口拉取消息;
下图中的Message Storage可认为是nameserver+broker

大体的结构示意图

docker pull apache/rocketmq:5.1.0
docker run -d -p 9876:9876 --name rmqnamesrv apache/rocketmq:5.1.0 sh mqnamesrv
docker run命令选项解释
--name rmqnamesrv,指定容器的名称为rmqnamesrvsh mqnamesrv,启动mqnamesrv,是个脚本文件进入容器docker exec -it 容器id /bin/bash后能看到mqnamesrv两个文件,
[rocketmq@99e974741937 bin]$ ls -l mqnames*
-rwxr-xr-x 1 rocketmq rocketmq 1472 Feb 14 2023 mqnamesrv
-rwxr-xr-x 1 rocketmq rocketmq 1165 Feb 14 2023 mqnamesrv.cmd
在宿主机上,创建/etc/rocketmq/conf/broker.conf文件,添加如下配置
brokerIP1 = 宿主机ip
namesrvAddr = 宿主机ip:9876
为了实现客户端与broker的通信可达性,这里必须要指定ip为 宿主机ip,默认使用的docker私有ip,客户端与私有ip通信不可达;
docker run -d -p 10909:10909 -p 10911:10911 \
-v /etc/rocketmq/conf/broker.conf:/etc/rocketmq/conf/broker.conf \
--name rmqbroker \
--link rmqnamesrv:namesrv \
-e "NAMESRV_ADDR=namesrv:9876" \
apache/rocketmq:5.1.0 \
sh mqbroker \
-n namesrv:9876 \
-c /etc/rocketmq/conf/broker.conf \
docker run命令选项解释
-v /etc/rocketmq/conf/broker.conf:/etc/rocketmq/conf/broker.conf,将宿主机中的配置文件挂载到容器中--link rmqnamesrv:namesrv,指定源容器的别名为namesrv,进入容器后查看/etc/hosts文件,cat /etc/hosts[rocketmq@87e707e2bb10 bin]$ cat /etc/hosts
127.0.0.1 localhost
172.18.0.2 namesrv 99e974741937 rmqnamesrv //源容器的ip和别名、源容器的id和源容器名称
172.18.0.3 87e707e2bb10 //本容器的ip和容器id
sh mqbroker命令选项解释
-n namesrv:9876,指定broker的nameserver地址,–link指定的别名,在这里起作用了;-c /etc/rocketmq/conf/broker.conf,指定配置文件顺便说一下,根据关于对docker run --link的理解,docker 已经不建议使用--link,docker network用来替代link,对等的使用docker run --network networkname --network-alias networkAlias
--network networkname,加入指定网络--network-alias networkAlias,本容器的网络别名经确认,由于操作失误,宿主机上的/etc/rocketmq/conf/broker.conf的确是一个文件夹,删除重新创建为文件就可以了;docker下安装rocketmq错误提示:/opt/rocketmq/conf/broker.conf (Is a directory)提到是命令换行的缘故,经确认这种说法是错误的,命令是可以换行的。
docker pull apacherocketmq/rocketmq-dashboard:latest
docker run -d --name rocketmq-dashboard -e "JAVA_OPTS=-Drocketmq.namesrv.addr=宿主机ip:9876" -p 8080:8080 -t apacherocketmq/rocketmq-dashboard:latest

打开后,报org.apache.rocketmq.remoting.exception.RemotingConnectException: connect to 错误,在此容器中执行telnet又报telnet: connect to address IP: No route to host ,确认是网络不通,参考Docker 容器访问宿主机报错 - No route to host执行以下命令解决,注意将172.18.0.0改为容器所在网段ip(docker inspect 容器id|grep -i ip)
firewall-cmd --permanent --zone=public --add-rich-rule='rule family=ipv4 source address=172.18.0.0/16 accept'
firewall-cmd --reload