一、背景
由于公司内部所有应用都在往K8S上迁移,为了提供发布订阅是消息的最基本功能,决定在生产环境搭建一套RocketMQ集群。
生产中目前所用版本为:v4.3.2
1.1 集群网络架构
如上图所示, RocketMQ的部署结构有以下特点:
- Name Server是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。
- Broker部署相对复杂,Broker分为Master与Slave,一个Master可以对应多个Slave,但是一个Slave只能对应一个Master,Master与Slave的对应关系通过指定相同的BrokerName,不同的BrokerId来定义,BrokerId为0表示Master,非0表示Slave。Master也可以部署多个。每个Broker与Name Server集群中的所有节点建立长连接,定时注册Topic信息到所有Name Server。
- Producer与Name Server集群中的其中一个节点(随机选择)建立长连接,定期从Name Server取Topic路由信息,并向提供Topic服务的Master建立长连接,且定时向Master发送心跳。Producer完全无状态,可集群部署。
- Consumer与Name Server集群中的其中一个节点(随机选择)建立长连接,定期从Name Server取Topic路由信息,并向提供Topic服务的Master、Slave建立长连接,且定时向Master、Slave发送心跳。Consumer既可以从Master订阅消息,也可以从Slave订阅消息,订阅规则由Broker配置决定。
- Server。
二、集群介绍
2.1 单个Master
- 这种方式风险较大,一旦Broker重启或者宕机时,会导致整个服务不可用,不建议线上环境使用。
2.2 多 Master 模式
- 一个集群无 Slave,全是 Master,例如 2 个 Master 或者 3 个 Master。
2.3 多 Master 多 Slave 模式,同步刷盘
- 每个 Master 配置一个 Slave,有多对Master-Slave,HA采用同步双写方式,主备都写成功,向应用返回成功。
2.4 多 Master 多 Slave 模式,异步刷盘
- 每个 Master 配置一个 Slave,有多对Master-Slave,HA采用异步复制方式,主备有短暂消息延迟,毫秒级。
三、镜像制作
3.1 name server镜像制作
3.1.1 JAVA运行环境
3.1.2 下载、解压
- 下载rocketmq-all-4.3.2
wget https://archive.apache.org/dist/rocketmq/4.3.2/rocketmq-all-4.3.2-bin-release.zip
- 解压
tar -xf rocketmq-all-4.3.2-bin-release.zip
3.1.3 编写Dockerfile
- 拷贝rocketmq-4.3.2到容器内,启动name server,暴露默认的9876端口
] # vim Dockerfile
FROM registry.moguyun.com/centos:7.6
MAINTAINER lijun registry.moguyun.com
ENV REFRESHED_AT 2019-12-20
ENV MQ_HOME=/opt/mq-namesrv
ADD rocketmq-all-4.3.2-bin-release $MQ_HOME
EXPOSE 9876
CMD ["sh","/opt/mq-namesrv/bin/mqnamesrv"]
3.1.4 构建,推送
- 构建镜像
docker build -t registry-vpc.cn-***.aliyuncs.com/moguyun-prod/common:mq-namesrv-4.3.2 .
- 推送镜像
docker push registry-vpc.cn-shenzhen.aliyuncs.com/moguyun-prod/common:mq-namesrv-4.3.2
3.2 broker镜像制作
3.2.1 环境准备
- 准备好JAVA环境和rocketmq-4.3.2文件夹,步骤同3.1.1~3.1.2
3.2.2 编写Dockerfile
- 创建指定用户,通过指定用户启动服务
- 默认name server有三例,也可以通过传入不同的$MQ_NAMESRV来实现name server的动态配置,通过传入不同的$MQ_BROKER_CONF来创建不同的broker。
FROM registry.moguyun.com/centos:7.6
MAINTAINER lijun registry.moguyun.com
ENV REFRESHED_AT 2019-09-30
ENV MQ_HOME /opt/mq-broker
ENV MQ_USER messageQueue
ENV MQ_NAMESRV "mq1-mg-addr:9876;mq2-mg-addr:9876;mq3-mg-addr:9876"
ENV MQ_BROKER_CONF "conf/2m-2s-async/broker-a.properties"
ADD mq-broker $MQ_HOME
WORKDIR $MQ_HOME
RUN groupadd $MQ_USER && useradd $MQ_USER -g $MQ_USER -s /sbin/nologin && \
echo "cat /bin/sysinit.sh" >> /bin/sysinit.sh && \
echo "chown -R $MQ_USER:$MQ_USER $MQ_HOME /home/$MQ_USER" >> /bin/sysinit.sh && \
echo 'echo "MQ_NAMESRV=${1}" && echo "MQ_BROKER_CONF=${2}"' >> /bin/sysinit.sh && \
echo 'su '$MQ_USER' -s /bin/bash -c "cd '$MQ_HOME'/bin ; sh mqbroker -n \"${1}\"
-c \"'$MQ_HOME'/${2}\" "' >> /bin/sysinit.sh && \
chmod +x /bin/sysinit.sh
EXPOSE 10911
CMD ["sh","-c","/bin/sysinit.sh \"$MQ_NAMESRV\" \"$MQ_BROKER_CONF\""]
3.2.3 构建,推送
- 构建镜像
docker build -t registry-vpc.cn-***.aliyuncs.com/moguyun-prod/common:mq-broker-4.3.2 .
- 推送镜像
docker push registry-vpc.cn-shenzhen.aliyuncs.com/moguyun-prod/common:mq-broker-4.3.2
四、集群搭建
由于生产环境选取的是
多Master多Slave,异步刷盘
的方案,所以我们准备创建3个name server,两组broker,每个master配置一个slave
4.1 name server集群搭建
4.1.1 创建无状态【deployment】应用
- 填入应用名称,副本数量,应用类型
4.1.2 查看参数
- 由于制作好的镜像已经push到指定镜像仓库了
- 在选择mq-namesrv-4.3.2镜像后,K8S平台会读取Dockerfile里面定义好的ENV,由于name server不需要更改任何参数,直接构建应用即可
4.1.3 验证name server是否启动成功
1.由输出日志可以看出,第一个name server节点正常启动
4.1.4 创建service
- 创建service name为mq1-mg-addr的service,指向的后端应用为 mq-namesvr1
- K8S集群是通过service name访问后端pod的,访问mq1-mg-addr:9876就可以访问后端mq-namesvr1
4.1.5 创建name server和service
- 分别创建两个名称为 mq-namesrv2,mq-namesrv3的无状态应用
- 分别创建两个名称为 mq2-mg-addr,mq2-mg-addr的服务
4.2 broker集群搭建
4.2.1 创建无状态【deployment】应用
- 填入应用名称,副本数量,无状态应用类型
4.2.2 传入参数【MQ_BROKER_CONF】
- 传入broker-a.properties,说明创建的pod为broker的master
- 传入broker-a-s.properties,说明创建的pod为broker的slave
4.2.3 验证broker是否启动成功
- 由日志看出broker-a已经启动成功了,不同的pod分别加载了 broker-a.properties,broker-a-s.properties配置
- name server是mq1-mg-addr:9876;mq2-mg-addr:9876;mq3-mg-addr:9876
4.2.4 创建broker
- 分别创建两个名称为 mq-broker-b,mq-broker-b-s的无状态应用
- 分别传入broker-a.properties,broker-b-s.properties创建
至此:RocketMQ 多Master多Slave 模式,异步刷盘集群已经运行在阿里云K8S环境了。