RocketMQ 是阿里巴巴在 2012 年开源的消息队列产品,用 Java 语言实现,在设计时参考了 Kafka,并做出了自己的一些改进,后来捐赠给 Apache 软件基金会,2017 正式毕业,成为 Apache 的顶级项目。RocketMQ 在阿里内部被广泛应用在订单,交易,充值,流计算,消息推送,日志流式处理,Binglog 分发等场景。经历过多次双十一考验,它的性能、稳定性和可靠性都是值得信赖的。我们今天就在 windows下搭建RocketMQ多Master多Slave模式(同步)的集群。
1 准备工作 1.1 下载RocketMQ RocketMQ版本:4.7.1
下载地址
1.2 环境要求
Linux64位系统
JDK1.8(64位)
源码安装需要安装Maven 3.2.x
2 安装RocketMQ 2.1 安装步骤 本教程以二进制包方式安装
解压安装包
进入安装目录
2.2 目录介绍
bin:启动脚本,包括shell脚本和CMD脚本
conf:实例配置文件 ,包括broker配置文件、logback配置文件等
lib:依赖jar包,包括Netty、commons-lang、FastJSON等
3 配置mqnamesrv双主 在RocketMQ 的配置文件夹的目录下,分别创建文件namesrv-a.properties、namesrv-b.properties
内容分别是
1 2 3 listenPort=9876 listenPort=9870
即表示namesrv-a监听端口是9876,namesrv-b监听端口是9870.
3.1 启动双主namesrv 1 2 3 4 start mqnamesrv.cmd -c D:/ProgramFiles/rocketmq-all-4.7.1/conf/namesrv/namesrv-a.properties start mqnamesrv.cmd -c D:/ProgramFiles/rocketmq-all-4.7.1/conf/namesrv/namesrv-b.properties
启动成功会在终端打印
1 The Name Server boot success serializeType=JSON
4 配置broker双主双从 此次我们采用多Master多Slave模式(同步)的方式,每个Master配置一个Slave,有多对Master-Slave,HA采用同步双写方式,即只有主备都写成功,才向应用返回成功,这种模式的优缺点如下:
优点:数据与服务都无单点故障,Master宕机情况下,消息无延迟,服务可用性与数据可用性都非常高;
缺点:性能比异步复制模式略低(大约低10%左右),发送单个消息的RT会略高,且目前版本在主节点宕机后,备机不能自动切换为主机。
namesrvAddr 我们就不直接写到配置文件里,我们采用在命令行的形式来指定 namesrvAddr
4.1 broker-a 的配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 # broker-a 的配置 brokerClusterName=DefaultCluster # broker名字,注意此处不同的配置文件填写的不一样 brokerName=broker-a brokerId=0 # nameServer地址,分号分割 # namesrvAddr=127.0.0.1:9876;127.0.0.1:9870 # 在发送消息时,自动创建服务器不存在的topic,默认创建的队列数 defaultTopicQueueNums=4 # 是否允许 Broker 自动创建Topic,建议线下开启,线上关闭 autoCreateTopicEnable=true # 是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭 autoCreateSubscriptionGroup=true # Broker 对外服务的监听端口, listenPort=10911 brokerIP1=127.0.0.1 brokerIP2=127.0.0.1 deleteWhen=04 fileReservedTime=48 brokerRole=SYNC_MASTER flushDiskType=ASYNC_FLUSH waitTimeMillsInSendQueue=500 # 存储路径 storePathRootDir=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-a/broker-a # commitLog 存储路径 storePathCommitLog=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-a/broker-a/commitlog # 消费队列存储路径存储路径 storePathConsumeQueue=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-a/broker-a/consumequeue # 消息索引存储路径 storePathIndex=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-a/broker-a/index # checkpoint 文件存储路径 storeCheckpoint=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-a/broker-a/checkpoint # abort 文件存储路径 abortFile=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-a/broker-a/abort
4.2 broker-a-s 的配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 # broker-a -s 的配置 brokerClusterName=DefaultCluster brokerName=broker-a brokerId=1 listenPort=10931 # nameServer地址,分号分割 # namesrvAddr=127.0.0.1:9876;127.0.0.1:9870 brokerIP1=127.0.0.1 brokerIP2=127.0.0.1 deleteWhen=04 fileReservedTime=48 brokerRole=SLAVE flushDiskType=ASYNC_FLUSH # 存储路径 storePathRootDir=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-a-s/broker-a-s # commitLog 存储路径 storePathCommitLog=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-a-s/broker-a-s/commitlog # 消费队列存储路径存储路径 storePathConsumeQueue=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-a-s/broker-a-s/consumequeue # 消息索引存储路径 storePathIndex=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-a-s/broker-a-s/index # checkpoint 文件存储路径 storeCheckpoint=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-a-s/broker-a-s/checkpoint # abort 文件存储路径 abortFile=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-a-s/broker-a-s/abort
4.3 broker-b 的配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 # broker-b 的配置 brokerClusterName=DefaultCluster brokerName=broker-b brokerId=0 # nameServer地址,分号分割 # namesrvAddr=127.0.0.1:9876;127.0.0.1:9870 # 在发送消息时,自动创建服务器不存在的topic,默认创建的队列数 defaultTopicQueueNums=4 # 是否允许 Broker 自动创建Topic,建议线下开启,线上关闭 autoCreateTopicEnable=true # 是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭 autoCreateSubscriptionGroup=true # Broker 对外服务的监听端口, listenPort=10951 brokerIP1=127.0.0.1 brokerIP2=127.0.0.1 deleteWhen=04 fileReservedTime=48 brokerRole=SYNC_MASTER flushDiskType=ASYNC_FLUSH waitTimeMillsInSendQueue=500 # 存储路径 storePathRootDir=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-b/broker-b # commitLog 存储路径 storePathCommitLog=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-b/broker-b/commitlog # 消费队列存储路径存储路径 storePathConsumeQueue=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-b/broker-b/consumequeue # 消息索引存储路径 storePathIndex=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-b/broker-b/index # checkpoint 文件存储路径 storeCheckpoint=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-b/broker-b/checkpoint # abort 文件存储路径 abortFile=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-b/broker-b/abort
4.4 broker-b-s 的配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 # broker-b-s 的配置 brokerClusterName=DefaultCluster brokerName=broker-b brokerId=1 listenPort=10971 # nameServer地址,分号分割 # namesrvAddr=127.0.0.1:9876;127.0.0.1:9870 # 可以不配置 brokerIP1=127.0.0.1 brokerIP2=127.0.0.1 deleteWhen=04 fileReservedTime=48 brokerRole=SLAVE flushDiskType=ASYNC_FLUSH # 存储路径 storePathRootDir=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-b-s/broker-b-s # commitLog 存储路径 storePathCommitLog=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-b-s/broker-b-s/commitlog # 消费队列存储路径存储路径 storePathConsumeQueue=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-b-s/broker-b-s/consumequeue # 消息索引存储路径 storePathIndex=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-b-s/broker-b-s/index # checkpoint 文件存储路径 storeCheckpoint=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-b-s/broker-b-s/checkpoint # abort 文件存储路径 abortFile=D:/ProgramFiles/rocketmq-all-4.7.1/store-broker-b-s/broker-b-s/abort
4.5 启动双主双从boker 1 2 3 4 5 6 7 start mqbroker.cmd -c D:/ProgramFiles/rocketmq-all-4.7.1/conf/2m-2s-sync/broker-a.properties -n "127.0.0.1:9876;127.0.0.1:9870" start mqbroker.cmd -c D:/ProgramFiles/rocketmq-all-4.7.1/conf/2m-2s-sync/broker-a-s.properties -n "127.0.0.1:9876;127.0.0.1:9870" start mqbroker.cmd -c D:/ProgramFiles/rocketmq-all-4.7.1/conf/2m-2s-sync/broker-b.properties -n "127.0.0.1:9876;127.0.0.1:9870" start mqbroker.cmd -c D:/ProgramFiles/rocketmq-all-4.7.1/conf/2m-2s-sync/broker-b-s.properties -n "127.0.0.1:9876;127.0.0.1:9870"
5 配置rocketmq-console RocketMQ
有一个对其扩展的开源项目incubator-rocketmq-externals ,这个项目中有一个子模块叫rocketmq-console
,这个便是管理控制台项目了,先将incubator-rocketmq-externals 拉到本地,因为我们需要自己对rocketmq-console
进行编译打包运行。
5.1 下载并编译打包 1 2 3 git clone https://github.com/apache/rocketmq-externals cd rocketmq-console mvn clean package -Dmaven.test.skip=true
注意:打包前在rocketmq-console
中配置namesrv
集群地址:
1 2 server.port=80 rocketmq.config.namesrvAddr=127.0.0.1:9876;192.168.25.138:9870
启动rocketmq-console:
1 java -jar rocketmq-console-ng-2.0.0.jar
注意 你执行上述命令之后可能得到的 jar 包的名字和我的不一样,毕竟人家也是一直在更新版本,注意看自己对应目录下的文件,适当替换就行。
启动成功后,我们就可以通过浏览器访问http://localhost:80
进入集群界面了如下图:
6 在搭建过程中出现的问题 6.1 Lock failed,MQ already started 1 2 3 4 5 java.lang.RuntimeException: Lock failed,MQ already started at org.apache.rocketmq.store.DefaultMessageStore.start(DefaultMessageStore.java:227) at org.apache.rocketmq.broker.BrokerController.start(BrokerController.java:853) at org.apache.rocketmq.broker.BrokerStartup.start(BrokerStartup.java:64) at org.apache.rocketmq.broker.BrokerStartup.main(BrokerStartup.java:58)
出现这个问题 是因为我们在集群中master和slave共用一个storePath造成的,这个时候我们要启动的每一个broker要指定不一样的storePath 路径就行,也就是在我们的配置文件中修改即可,完美解决。
6.2 集群状态 SLAVE_NOT_AVAILABLE 主从的brokerName 一定要设置成一样的,主brokerName=broker-a 那么从的brokerName=broker-a,不然发送消息会出现 SLAVE_NOT_AVAILABLE
1 2 3 4 5 6 7 8 9 10 11 # broker名字,注意此处不同的配置文件填写的不一样 # broker-a 的配置 brokerClusterName=DefaultCluster brokerName=broker-a # broker-a -s 的配置 brokerClusterName=DefaultCluster brokerName=broker-a
6.3 消息发送出现 [TIMEOUT_CLEAN_QUEUE]broker busy 1 org.apache.rocketmq.client.exception.MQBrokerException: CODE: 2 DESC: [TIMEOUT_CLEAN_QUEUE]broker busy, start flow control for a while, period in queue: 205ms, size of queue: 2
解决方式就是合理设置waitTimeMillsInSendQueue的值: 清除发送线程池任务队列的等待时间。如果系统时间减去任务放入队列中的时间小于waitTimeMillsInSendQueue,本次请求任务暂时不移除该任务 默认200ms
1 waitTimeMillsInSendQueue=200
到此RocketMQ双主双从集群就搭建完毕。
参考资料
https://blog.csdn.net/chenzhong2010/article/details/106749258 https://blog.csdn.net/vucko/article/details/107487675 https://blog.csdn.net/jianghuiyun/article/details/77971583