RocketMQ发展历史
RocketMQ是一个由阿里巴巴开源的消息中间件, 2012年开源,2017年成为apache顶级项目。RocketMQ在阿里内部应用是非常广泛的,阿里内部的几千个应用都运行在RocketMQ之上,双十一期间需要处理亿万级别的消息,TPS可以达到几十万。目前支持Java、C/C++,Python、Go四种语言访问。
RocketMQ现在有两个版本,一个是社区开源版,一个是商业的云服务版(AliwareMQ)。最新版本:4.8.0(本文演示版本)。
它的核心设计借鉴了Kafka,所以我们在学习RocketMQ的时候,会发现很多和kafka相同的特性,但是在某些功能上和kafka又有较大的差异,它有以下一些特性:
- 支持集群模型、负载均衡、水平扩展能力
- 亿级别消息堆积能力
- 采用零拷贝的原理,顺序写盘,随机读
- 底层通信框架采用Netty NIO
- NameServer代替Zookeeper,实现服务寻址和服务协调
- 消息失败重试机制、消息可查询
- 强调集群无单点,可扩展,任意一点高可用,水平可扩展
- 经过多次双十一的考验
高可用架构
RocketMQ天生对集群的支持非常好,它有以下一些模式:
单Master
- 优点:除了配置简单没什么优点
- 缺点:不可靠,该机器重启或者宕机,将要导致整个服务不可用
多Master
- 优点:配置简单,性能最高
- 缺点:可能会有少量消息丢失(配置相关),单台机器重启或宕机期间,该机器下未被消费的消息在机器恢复前不可订阅,影响消息实时性
多Master多Slave
每个Master配一个Slave,有多对Master-Slave,集群采用异步复制方式,主备有短暂消息延迟,毫秒级
- 优点:性能同多Master几乎一样,实时性高,主备间切换对应用透明,不需人工干预
- 缺点:Master宕机或磁盘损坏时会有少量消息丢失
多Master多Slave
每个Master配一个Slave,有多对Master-Slave,集群采用同步双写方式,主备都写成功,向应用返回成功
- 优点:服务可用性与数据可用性非常高
- 缺点:性能比异步集群略低,当前版本主宕备不能自动切换为主
二主二从异步集群安装
本文采用的是二主二从安装模式,即第四种多Master多Slave
端口规划
首先我买了两台云服务器,平时我会用来学习安装一些中间件,比较方便,大家有条件的话也可以买下,当然也可以通过在本地安装虚拟机的方式来操作。
接下来我要通过这两台服务器来实现二主二从的安装,首先对它们的端口进行一下规划
第一台机器 42.192.77.73
#端口规划:
9876 NameServer1
10910 BrokerA-master
10921 BrokerB-slave
第二台机器 39.103.144.86
#端口规划:
9876 NameServer2
10920 BrokerB-master
10911 BrokerA-slave
画图看上去更加清晰明了一些
下载
从官网rocketmq.apache.org/进去获得最新的下载地址,红框里标注出来的
这里的地址都可以,下载下来
cd /jackxu
wget https://mirror.bit.edu.cn/apache/rocketmq/4.8.0/rocketmq-all-4.8.0-bin-release.zip
下载好后解压,改个名字
unzip rocketmq-all-4.8.0-bin-release.zip
mv unzip rocketmq-all-4.8.0-bin-release.zip rocketmq
配置第一台机器
在两台机器上都下载、解压好。在rocketmq/conf目录下,有三种建议配置模式:
- 2m-2s-async(2主2从异步) —— 本文采用这种
- 2m-2s-sync (2主2从同步)
- 2m-noslave (2主)
现在需要修改两台机器上2m-2s-async这个目录中的文件。在42.192.77.73机器上修改broker-a.properties
cd /jackxu/rocketmq/conf/2m-2s-async
vim broker-a.properties
修改集群名字
brokerClusterName=jackxu-cluster
增加的内容
#Broker 对外服务的监听端口
listenPort=10910
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
#nameServer地址,分号分割
namesrvAddr=39.103.144.86:9876;42.192.77.73:9876
#存储路径
storePathRootDir=/jackxu/rocketmq/store/broker-a
#commitLog 存储路径
storePathCommitLog=/jackxu/rocketmq/store/broker-a/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/jackxu/rocketmq/store/broker-a/consumequeue
#消息索引存储路径
storePathIndex=/jackxu/rocketmq/store/broker-a/index
#checkpoint 文件存储路径
storeCheckpoint=/jackxu/rocketmq/store/checkpoint
#abort 文件存储路径
abortFile=/jackxu/rocketmq/store/abort
修改broker-b-s.properties
vim broker-b-s.properties
修改集群名字
brokerClusterName=jackxu-cluster
增加的内容
#Broker 对外服务的监听端口
listenPort=10921
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
#nameServer地址,分号分割
namesrvAddr=39.103.144.86:9876;42.192.77.73:9876
#存储路径
storePathRootDir=/jackxu/rocketmq/store/broker-b-s
#commitLog 存储路径
storePathCommitLog=/jackxu/rocketmq/store/broker-b-s/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/jackxu/rocketmq/store/broker-b-s/consumequeue
#消息索引存储路径
storePathIndex=/jackxu/rocketmq/store/broker-b-s/index
#checkpoint 文件存储路径
storeCheckpoint=/jackxu/rocketmq/store/checkpoint
#abort 文件存储路径
abortFile=/jackxu/rocketmq/store/abort
配置第二台机器
在39.103.144.86机器上修改broker-b.properties
cd /jackxu/rocketmq/conf/2m-2s-async
vim broker-b.properties
修改集群名字
brokerClusterName=jackxu-cluster
增加的内容
#Broker 对外服务的监听端口
listenPort=10920
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
#nameServer地址,分号分割
namesrvAddr=39.103.144.86:9876;42.192.77.73:9876
#存储路径
storePathRootDir=/jackxu/rocketmq/store/broker-b
#commitLog 存储路径
storePathCommitLog=/jackxu/rocketmq/store/broker-b/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/jackxu/rocketmq/store/broker-b/consumequeue
#消息索引存储路径
storePathIndex=/jackxu/rocketmq/store/broker-b/index
#checkpoint 文件存储路径
storeCheckpoint=/jackxu/rocketmq/store/checkpoint
#abort 文件存储路径
abortFile=/jackxu/rocketmq/store/abort
修改broker-a-s.properties
vim broker-a-s.properties
修改集群名字
brokerClusterName=jackxu-cluster
增加的内容
#Broker 对外服务的监听端口
listenPort=10911
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
#nameServer地址,分号分割
namesrvAddr=39.103.144.86:9876;42.192.77.73:9876
#存储路径
storePathRootDir=/jackxu/rocketmq/store/broker-a-s
#commitLog 存储路径
storePathCommitLog=/jackxu/rocketmq/store/broker-a-s/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/jackxu/rocketmq/store/broker-a-s/consumequeue
#消息索引存储路径
storePathIndex=/jackxu/rocketmq/store/broker-a-s/index
#checkpoint 文件存储路径
storeCheckpoint=/jackxu/rocketmq/store/checkpoint
#abort 文件存储路径
abortFile=/jackxu/rocketmq/store/abort
创建数据目录
第一台机器42.192.77.73执行,只需要执行一次
mkdir -p /jackxu/rocketmq/store/broker-a /jackxu/rocketmq/store/broker-a/consumequeue /jackxu/rocketmq/store/broker-a/commitlog /jackxu/rocketmq/store/broker-a/index /jackxu/rocketmq/logs /jackxu/rocketmq/store/broker-b-s /jackxu/rocketmq/store/broker-b-s/consumequeue /jackxu/rocketmq/store/broker-b-s/commitlog /jackxu/rocketmq/store/broker-b-s/index
第二台机器39.103.144.86执行,只需要执行一次
mkdir -p /jackxu/rocketmq/store/broker-a-s /jackxu/rocketmq/store/broker-a-s/consumequeue /jackxu/rocketmq/store/broker-a-s/commitlog /jackxu/rocketmq/store/broker-a-s/index /jackxu/rocketmq/logs /jackxu/rocketmq/store/broker-b /jackxu/rocketmq/store/broker-b/consumequeue /jackxu/rocketmq/store/broker-b/commitlog /jackxu/rocketmq/store/broker-b/index
启动两个NameServer
在两台机器分别执行,& 表示在后台运行,默认情况下,nameserver监听的是9876端口
nohup sh /jackxu/rocketmq/bin/mqnamesrv >/jackxu/rocketmq/logs/mqnamesrv.log 2>&1 &
查看日志
tail -f /jackxu/rocketmq/logs/mqnamesrv.log
启动Broker
启动的时候按照下面的顺序来,-c 是指定broker的配置文件
1、启动73的A主
nohup sh /jackxu/rocketmq/bin/mqbroker -c /jackxu/rocketmq/conf/2m-2s-async/broker-a.properties > /jackxu/rocketmq/logs/broker-a.log 2>&1 &
2、启动86的A从
nohup sh /jackxu/rocketmq/bin/mqbroker -c /jackxu/rocketmq/conf/2m-2s-async/broker-a-s.properties > /jackxu/rocketmq/logs/broker-a-s.log 2>&1 &
3、启动86的B主
nohup sh /jackxu/rocketmq/bin/mqbroker -c /jackxu/rocketmq/conf/2m-2s-async/broker-b.properties > /jackxu/rocketmq/logs/broker-b.log 2>&1 &
4、启动73的B从
nohup sh /jackxu/rocketmq/bin/mqbroker -c /jackxu/rocketmq/conf/2m-2s-async/broker-b-s.properties > /jackxu/rocketmq/logs/broker-b-s.log 2>&1 &
查看日志
tail -f /jackxu/rocketmq/conf/2m-2s-async/broker-a.properties
tail -f /jackxu/rocketmq/conf/2m-2s-async/broker-a-s.properties
tail -f /jackxu/rocketmq/conf/2m-2s-async/broker-b.properties
tail -f /jackxu/rocketmq/conf/2m-2s-async/broker-b-s.properties
检查是否启动成功
输入jps命令,一共四个进程没问题
但是大多数情况下不会这么顺利,我在安装中有一些坑点:
- 1、没有安装jdk,因为这是我新的服务器,上面是没有jdk环境的,大家知道rocketmq是用java写的,所以需要有java环境才能运行,包括jps命令就是查看java进程
- 2、内存不足,因为默认的配置文件设置了很大的内存,但是我的机器只有1核2G,肯定是不够的,所以在启动的时候会报内存不足
解决办法就是修改配置文件
vim /jackxu/rocketmq/bin/runserver.sh
vim /jackxu/rocketmq/bin/runbroker.sh
把NameServer和Broker的内存大小都改小一点,然后重新启动即可
关闭命令
停止服务的时候需要注意,要先停止broker,其次停止nameserver。
cd /jackxu/rocketmq/bin
sh mqshutdown namesrv
sh mqshutdown broker
web控制台安装
与kafka不同的是,rocket官方提供了一个可视化控制台,大家可以在这里下载
https://github.com/apache/rocketmq-externals
这个是rocketmq的扩展,里面不仅包含控制台的扩展,也包含对大数据flume、hbase等组件的对接和扩展。
下载
下载源码,一般下载速度会比较慢,等不及的话可以去网盘下载链接:
cd /jackxu
wget https://github.com/apache/rocketmq-externals/archive/master.zip
解压
unzip master.zip
修改配置文件
cd /jackxu/rocketmq-externals-master/rocketmq-console/src/main/resources
vim application.properties
#这是一个spring boot项目,我们需要修改里面的参数
#修改端口号:
server.port=7298
#修改name server地址(多个地址用英文分号隔开)
rocketmq.config.namesrvAddr=39.103.144.86:9876;42.192.77.73:9876
打包
打成一个jar包, 这里需要先安装maven,编译慢的话可以替换成淘宝的镜像
cd /jackxu/rocketmq-externals-master/rocketmq-console
mvn clean package -Dmaven.test.skip=true
启动jar包
cd target
java -jar rocketmq-console-ng-2.0.0.jar
访问
访问一下 http://42.192.77.73:7298/ ,可以看到都已经启动成功了
踩坑点
这里有两个踩坑点,在启动的时候会报错
- (1)spring boot启动的时候报连接不上39.103.144.86:9876;42.192.77.73:9876,这里我的第一反应是防火墙的原因,关闭一下
systemctl disable firewalld.service
再次启动还是不行,然后我的第二个反应是端口没有开放,telnet一下
telnet 42.192.77.73 9876
果然telnet不通,原因是这样的,我安装在云服务器上,默认端口是不开放的,需要到控制台打开,这也算是一个经验吧。
- (2)再次启动的时候又报了另一个错误,连接不上172.26.182.88:9876,当时我就奇怪了,我写的地址里没有这个地址啊,怎么在连接它,而且这个IP看上去又像是内网地址,后来我打开阿里云控制台一看,果真是这台机器的内网地址,然后我又百度了一番,大概原因就是RocketMQ是阿里开源的,而那台机器又是阿里云的机器,它的源码里应该是优先连接到阿里云的内网地址,网上的做法是在配置文件里面显式的加上公网地址即可解决。
#新增公网IP
brokerIP1=39.103.144.86
控制台介绍
- 运维:主要是设置nameserver和配置vipchannel。
- 驾驶舱:控制台的dashboard,可以分别按broker和主题来查看消息的数量和趋势。
- 集群:整个RocketMQ的集群情况,包括分片,编号,地址,版本,消息生产和消息消费的TPS等,这个在做性能测试的时候可以作为数据指标。
- 主题:即topic,可以新增/更新topic,也可以查看topic的信息,如状态,路由,消费者管理和发送消息等。
- 消费者:可以在当前broker中查看/新建消费者group,包括消费者信息和消费进度。
- 生产者:可以在当前broker中查看生产组下的生产者group,包括生产者信息和生产者状态。
- 消息:可以按照topic,messageID,messageKey分别查询具体的消息。
- 用户中心:切换语言和登录相关(登录需要在console的配置中打开对应配置,默认不需要登录)。
其中最常用的是集群,主题,消费者和消息这四部分。
配置文件说明
下面介绍一下安装RocketMQ配置文件里面的属性首先是集群名字相同,上面四台机器的集群名字都叫 brokerClusterName=jackxu-cluster,其次是连接到相同的NameServer,namesrvAddr=39.103.144.86:9876;42.192.77.73:9876。在配置文件中brokerId=0代表master,brokerId=1代表slave。
在配置文件中还有这两个属性
brokerRole在master broker可以配置成SYNC_MASTER或者ASYNC_MASTER,在slave broker统一配置成SLAVE
流程图
我们推荐的配置是异步刷盘+同步复制。
HA与故障转移
在之前的版本中,RocketMQ只有master/slave一种部署方式,一组broker中有一个master,有0到多个slave,这种模式下提供了一定的高可用性。
master在挂了的情况下,slave仍然可以提供读服务。默认情况下,读写都在master上,如果开启了slaveReadEnable=true,slave也可以参与读负载,但是是在master积压的消息超过了物理内存的40%,才会默认转向brokerId为1的从服务器读取,具体转向哪台机器由whichBrokerWhenConsumeSlowly参数控制。
org.apache.rocketmq.common.subscription.SubscriptionGroupConfig
private long whichBrokerWhenConsumeSlowly=1;
由于是多主的存在,当一个master挂了以后,可以写到其他的master上。
RocketMQ 2019年3月发布的4.5.0版本中,利用Dledger技术解决了自动选主的问题。Dledger就是一个基于raft协议的commitlog存储库,也是RocketMQ实现新的高可用多副本架构的关键。它的优点是不需要引入外部组件,自动选主逻辑集成到各个节点的进程中,节点之间通过通信就可以完成选主。
架构图
在这种情况下,commitlog是Dledger管理的,具有选主的功能。默认是不开启,如果需要开启,需要在配置文件里面添加以下配置:
# 是否启用DLedger
enableDLegerCommitLog=true
# DLedger Raft Group的名字
dLegerGroup=broker-a
# DLedger Group内各节点的地址和端口,至少需要3个节点
dLegerPeers=n0-192.168.44.163:10911;n1-192.168.44.164:10911;n2-192.168.44.165:10911
# 本节点id
dLegerSelfId=n0
结语
小伙伴在学习一个中间件的时候一定要动手实践安装,首先是体验一下安装的过程氛围,了解一些参数配置,虽然我们平时可能接触不到,但是学习还是需要的,不一定需要精,至少是要会。
来源:jack_xu | https://juejin.cn/post/692950...