这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战
搭建管理控制台
上篇搭建了RocketMQ主从模式的集群,但是没有解决单点故障问题,master挂掉,服务就不可用了。所以本章将介绍一下使用Dleger搭建一个高可用的集群。
首先先搭建一个RocketMQ的控制台。
前面提到过RocketMQ源码没有提供控制台,但是RcoektMQ的社区提供了一个控制台:
地址:控制台下载地址
下载完成后进入其中的rocket-console目录,使用maven进行编译(PS:需要自己安装mvn环境,这里不做说明,可自行百度)
使用名令:
mvn clean package -Dmaven.test.skip=true
复制代码
编译完成信息如下:
……
3 kB/s)
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/shared/maven-shared-utils/3.0.1/maven-shared-utils-3.0.1.jar (154 kB at 7.6 kB/s)
Downloaded from central: https://repo.maven.apache.org/maven2/org/iq80/snappy/snappy/0.4/snappy-0.4.jar (58 kB at 2.7 kB/s)
Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/3.0.24/plexus-utils-3.0.24.jar (247 kB at 8.3 kB/s)
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-core/3.0/maven-core-3.0.jar (527 kB at 15 kB/s)
[INFO] Building jar: /root/javadevtools/rocketmq/rocketmq-externals-master/rocketmq-console/target/rocketmq-console-ng-1.0.1-sources.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 18:24 min
[INFO] Finished at: 2021-08-08T21:53:25+08:00
[INFO] ------------------------------------------------------------------------
复制代码
主要看到BUILD SUCCESS即可。然后在rocketmq-console目录下可以看到新生成一个target目录,里面有运行的jar包。
但是这个时候要注意,在这个项目的
application.properties中需要指定nameserver的地址。默认这个属性是空的。该配置文件在项目的resources下
rocketmq.config.namesrvAddr=192.168.40.131:9876;192.168.40.132:9876;192.168.40.133:9876
复制代码
然后执行:
java -jar rocketmq-console-ng-1.0.1.jar
复制代码
看到如下信息表示执行成功:
首先是JVM running表示成功,后面会显示节点的心跳连接信息:如下:
[2021-08-08 22:23:00.288] INFO closeChannel: close the connection to remote address[192.168.40.132:9876] result: true
[2021-08-08 22:23:00.349] INFO closeChannel: close the connection to remote address[192.168.40.132:11009] result: true
[2021-08-08 22:23:30.315] INFO closeChannel: close the connection to remote address[192.168.40.133:10911] result: true
[2021-08-08 22:23:30.316] INFO closeChannel: close the connection to remote address[192.168.40.132:9876] result: true
[2021-08-08 22:23:30.316] INFO closeChannel: close the connection to remote address[192.168.40.132:11011] result: true
[2021-08-08 22:23:30.316] INFO closeChannel: close the connection to remote address[192.168.40.132:10911] result: true
[2021-08-08 22:23:30.316] INFO closeChannel: close the connection to remote address[192.168.40.133:10909] result: true
[2021-08-08 22:23:30.317] INFO closeChannel: close the connection to remote address[192.168.40.133:11011] result: true
[2021-08-08 22:23:30.317] INFO closeChannel: close the connection to remote address[192.168.40.132:10909] result: true
复制代码
然后在浏览器访问:ip+端口:
我的是:http://192.168.40.131:8080
可以看到如下界面:
比较直观的验证了上一章我们的集群是搭建成功了。
Dleger高可用集群搭建
主从结构只能做数据备份,并没有容灾功能。意味着当master节点挂掉后,slave节点是无法切换成master节点的。反之slave挂掉,对集群的影响不大。即当消费者要拉取的数据量很大的时候,RocketMQ有一定的机制会优先保证Master节点的性能,其他大部分数据会从slave拉取。所以slave挂掉,系统在大数据的冲击下,吞吐量会下降。
所以需要进行高可用的容灾备份,需要采用Dledger的方式来搭建高可用集群。注意,Dledger需要RocketMQ4.5以后的版本才支持。我使用的是4.7.1版本已经默认集成了dledger。
搭建方法
要搭建高可用的Broker集群,我们只需要配置conf/dleger下的配置文件即可。
这种模式是基于Raft协议的,是一个类似于zookeeper的paxos协议的选举协议,也是在集群中选举出一个leader,其他的就是follower。Raft协议基于休眠随机休眠机制的,选举过程会比paxos相对慢一些。
关于RocketMQ内存就不再赘述了,修改conf/dleger下的配置文件。与dleger相关的几个配置如下:
| name | 含义 | 举例 |
|---|---|---|
| enableDLegerCommitLog | 是否启动 DLedger | true |
| dLegerGroup | DLedger Raft Group的名字,建议和 brokerName 保持一致 | RaftNode00 |
| dLegerPeers | DLedger Group 内各节点的端口信息,同一个 Group 内的各个节点配置必须要保证一致 | n0-127.0.0.1:40911;n1-127.0.0.1:40912;n2-127.0.0.1:40913 |
| dLegerSelfId | 节点 id, 必须属于 dLegerPeers 中的一个;同 Group 内各个节要唯一 | n0 |
| sendMessageThreadPoolNums | 发送线程个数,建议配置成 Cpu 核数 | 16 |
配置节点文件
服务器配置说明如下:
| 服务器名称 | ip | 服务器启动服务 |
|---|---|---|
| dockerVm-》 主 | 192.168.40.131 | nameServer、mqbroker、rocket-extern可视化服务 |
| dockerVm2 -》从 | 192.168.40.132 | nameServer、mqbroker |
| dockerVm3-》从 | 192.168.40.133 | nameServer、broker |
dockerVm配置
修改broker-n0.conf文件:配置如下
# 集群名
brokerClusterName = RaftCluster
# broker组名,同一个RaftClusterGroup内,brokerName名要一样
brokerName=RaftNode00
# 监听的端口
listenPort=30911
# 你设置的NameServer地址和端口
namesrvAddr=192.168.40.131:9876;192.168.40.132:9876;192.168.40.133:9876
# store存放目录
storePathRootDir=/tmp/rmqstore/node00
# commitlog存放目录
storePathCommitLog=/tmp/rmqstore/node00/commitlog
# 是否开启Dledger
enableDLegerCommitLog=true
# 组节点名称
dLegerGroup=RaftNode00
# n0 n1 n2 分别是broker1,broker2,broker3 的 dLegerSelfId
# 例如:dLegerPeers=n0-服务器1的IP:40911;n1-服务器2的IP:40912;n2-服务器3的IP:40913
dLegerPeers=n0-192.168.40.131:40911;n1-192.168.40.132:40912;n2-192.168.40.133:40913
## must be unique
## 这个值必须是在同一个RaftClusterGroup内唯一的
dLegerSelfId=n0
# 发送线程个数,建议配置成 Cpu 核数
sendMessageThreadPoolNums=1
## 如果虚拟机配置了多个网卡,所以会绑定ip错误,需要指定自己虚拟机的ip,没有的话不用管,我的就没有
## brokerIP1=192.168.40.131
复制代码
dockerVm2的配置
修改broker-n1.conf文件:配置如下
brokerClusterName = RaftCluster
brokerName=RaftNode00
listenPort=30921
namesrvAddr=192.168.40.131:9876;192.168.40.132:9876;192.168.40.133:9876
storePathRootDir=/tmp/rmqstore/node01
storePathCommitLog=/tmp/rmqstore/node01/commitlog
enableDLegerCommitLog=true
dLegerGroup=RaftNode00
dLegerPeers=n0-192.168.56.102:40911;n1-192.168.56.103:40912;n2-192.168.56.104:40913
## must be unique
dLegerSelfId=n1
sendMessageThreadPoolNums=1
## 如果虚拟机配置了多个网卡,所以会绑定ip错误,需要指定自己虚拟机的ip,没有的话不用管,我的就没有
## brokerIP1=192.168.40.132
复制代码
dockerVm3的配置
修改broker-n1.conf文件:配置如下
brokerClusterName = RaftCluster
brokerName=RaftNode00
listenPort=30931
namesrvAddr=192.168.40.131:9876;192.168.40.132:9876;192.168.40.133:9876
storePathRootDir=/tmp/rmqstore/node02
storePathCommitLog=/tmp/rmqstore/node02/commitlog
enableDLegerCommitLog=true
dLegerGroup=RaftNode00
dLegerPeers=n0-192.168.40.131:40911;n1-192.168.40.132:40912;n2-192.168.40.133:40913
## must be unique
dLegerSelfId=n2
sendMessageThreadPoolNums=1
## 如果虚拟机配置了多个网卡,所以会绑定ip错误,需要指定自己虚拟机的ip,没有的话不用管,我的就没有
## brokerIP1=192.168.40.133
复制代码
启动服务
1.首先启动dockerVm的nameServer和mqbroker、以及可视化服务
./mqnamesrv
./mqbroker -c ../conf/dledger/broker-n0.conf
java -jar rocketmq-console-ng-1.0.1.jar
复制代码
2.接着启动dockerVm2的服务
./mqnamesrv
./mqbroker -c ../conf/dledger/broker-n1.conf
复制代码
3.接着启动dockerVm3的服务
./mqnamesrv
./mqbroker -c ../conf/dledger/broker-n2.conf
复制代码
全部启动后在网页查看cluster:
(PS: 此时应该是ip为192.168.40.131为主节点,但是我测试直接把主节点kill了,所以此时主节点经过删选变了)
从而也验证了集群的高可用。
(PS:在bin/dleger下有个fast-try.sh,这个脚本是在本地启动三个RocketMQ实例,搭建一个高可用的集群。读取的文件就是conf/dleger下的配置文件。但是要注意内存的配置。)
至此RocketMQ的集群搭建暂告一段落,其他的集群搭建方式与此类似,都是相关文件下的配置文件修改。不在赘述。不会的可以百度一波。教程都有。
调整系统参数
实际使用中,我们还需要根据实际的服务去调整RocketMQ的配置,这样才能让RocketMQ的优势发挥到最大。
这里以 runbroker.sh中对G1的配置举例:在runbroker.sh中的关键配置:
JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -
XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -
XX:SoftRefLRUPolicyMSPerMB=0"
JAVA_OPT="${JAVA_OPT} -verbose:gc -
Xloggc:${GC_LOG_DIR}/rmq_broker_gc_%p_%t.log -XX:+PrintGCDetails -
XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -
XX:+PrintAdaptiveSizePolicy"
JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -
XX:GCLogFileSize=30m"
复制代码
-XX:+UseG1GC:使用G1垃圾回收器;
-XX:G1HeapRegionSize=16m将G1的region块大小设为16m;
-XX:G1ReservePerCent: 在G1的老年代中预留了25%空闲内存,默认值是10%,RocketMQ把这个参数调大了;
-XX:InitiatingHeapOccupancyPercent=30:当堆内存的使用率达到30%就会启动G1垃圾收集器尝试回收垃圾,默认值是45%,RocketMQ把这个参数调小了,也就是提高了GC的频率,但是避免了垃圾对象过多,一次垃圾回收时间太长的问题;
RocketMQ的其他一些核心参数
sendMessageThreadPoolNums=16:默认值是16,表明Rocket内部使用的线程池数量是16个,其实这个参数可以根据机器的CPU核心进行适当调整。如果你的机器核心数量超过16个,就可以把参数适当调大。
Linux内核参数定制
ulimit:需要进行大量的网络通信和磁盘IO;
vm.extra_free_kbytes:告诉VM在后台回收(kswapd)启动的阈值与直接回收(通过分配进程)的阈值之间保留额外的可用内存。RocketMQ使用此参数来避免内存分配中的长延迟(与具体内核版本有关)
vm.min_free_kbytes,如果将其设置为低于1024KB,将会巧妙的将系统破坏,并且系统在高负载下容易出现死锁。
vm.max_map_count,限制一个进程可能具有的最大内存映射区域数。RocketMQ将使用mmap加载CommitLog和ConsumeQueue,因此建议将为此参数设置较大的值。
vm.swappiness,定义内核交换内存页面的积极程度。较高的值会增加攻击性,较低的值会减少交换量。建议将值设置为10来避免交换延迟。
File descriptor limits,RocketMQ需要为文件(CommitLog和ConsumeQueue)和网络连接打开文件描述符。我们建议设置文件描述符的值为655350。
PS: 这些参数在CentOS7中的配置文件都在 /proc/sys/vm目录下。
另外,RocketMQ的bin目录下有个os.sh里面设置了RocketMQ建议的系统内核参数,可以根据情况进行调整。




近期评论