前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >RocketMQ的集群

RocketMQ的集群

作者头像
Java廖志伟
发布2022-09-29 10:24:34
3510
发布2022-09-29 10:24:34
举报
文章被收录于专栏:高级开发进阶

RocketMQ集群架构

\

刚才的演示中,我们已经体验到了RocketMQ是如何工作的。这样,我们回头看RocketMQ的集群架构,就能够有更全面的理解了。

\

1、RocketMQ集群中的各个角色

\

一个完整的RocketMQ集群中,有如下几个角色

\

  1. Producer:消息的发送者;举例:发信者
  2. Consumer:消息接收者;举例:收信者
  3. Broker:暂存和传输消息;举例:邮局
  4. NameServer:管理Broker;举例:各个邮局的管理机构
  5. Topic:区分消息的种类;一个发送者可以发送消息给一个或者多个Topic;一个消息的接收者可以订阅一个或者多个Topic消息。我们之前的测试案例中,Topic是什么?topic='TopicTest'。现在你能看懂我们之前在broker.conf中添加的autoCreateTopicEnable=true这个属性的用处了吗?
  6. Message Queue:相当于是Topic的分区;用于并行发送和接收消息。在我们之前的测试案例中,一个queueId就代表了一个MessageQueue。有哪些queueId? 0,1,2,3四个MessageQueue,你都找到了吗?

\

2、RocketMQ集群搭建

\

1、机器环境

\

准备三台虚拟机,root密码 root ;IP地址:

代码语言:javascript
复制
机器1的ip worker1
机器2的ip worker2
机器3的ip worker3

这里特意不把每个机器的机器名定义得太过规范,比如master slave这样的,有助于更理解各项配置。

\

\

2、创建用户

\

useradd liaozhiwei

\

passwd liaozhiwei (密码输入 123qweasd)\

3、系统配置
免密登录

切换liaozhiwei用户,在worker1上 生成key

ssh-kengen

然后分发给其他机器

代码语言:javascript
复制
ssh-copy-id worker1
ssh-copy-id worker2
ssh-copy-id worker3

\

这样就可以在worker1上直接ssh 或者scp到另外的机器,不需要输密码了。\

关闭防火墙(生产环境不建议这么做,有被入侵的风险)
代码语言:javascript
复制
systemctl stop firewalld.service
firewall-cmd --state

生成环境开启防火墙

代码语言:javascript
复制
systemctl start firewalld 
systemctl enable firewalld

RocketMQ默认使用3个端口:9876 、10911 、11011 。

防火墙没有关闭的话,那么防火墙就必须开放这些端口: nameserver 默认使用 9876 端口 master 默认使用 10911 端口 slave 默认使用11011 端口

代码语言:javascript
复制
firewall-cmd --add-port=11011/tcp --permanent
firewall-cmd --add-port=10911/tcp --permanent
firewall-cmd --add-port=9876/tcp --permanent
firewall-cmd --reload
4、安装java

\

给liaozhiweir创建/rocketmq目录

\

上传jdk的tar包

\

vim /etc/profile,配置环境变量。source /etc/profile生效。

\

export JAVA_HOME=/opt/jdk/

5、安装RocketMQ

上传tar包,直接解压。然后配置环境变量

代码语言:javascript
复制
export ROCKETMQ_HOME=/opt/rocketmq

RocketMQ在4.5版本之前都不支持master宕机后slave自动切换。在4.5版本后,增加了基于Dleger实现的主从切换。这里用的目前最新的4.7.1版本

6、配置RocketMQ集群

我们为了便于观察,这次搭建一个2主2从异步刷盘的集群,所以我们会使用conf/2m-2s-async下的配置文件,实际项目中,为了达到高可用,一般会使用dleger。预备设计的集群情况如下:\

机器名

nameServer节点部署

broker节点部署

worker1

nameserver

worker2

nameserver

broker-a, broker-b-s

worker3

nameserver

broker-b,broker-a-s

所以修改的配置文件是进入rocketmq的config目录下修改2m-2s-async的配置文件。--只需要配置broker.conf。

\

代码语言:javascript
复制
在rocketmq的config目录下可以看到rocketmq建议的各种配置方式:

    2m-2s-async: 2主2从异步刷盘(吞吐量较大,但是消息可能丢失),
    2m-2s-sync:2主2从同步刷盘(吞吐量会下降,但是消息更安全),
    2m-noslave:2主无从(单点故障),然后还可以直接配置broker.conf,进行单点环境配置。
    而dleger就是用来实现主从切换的。集群中的节点会基于Raft协议随机选举出一个leader,其他的就都是follower。通常正式环境都会采用这种方式来搭建集群。

\

我们这次采用2m-2s-async的方式搭建集群。\

1、配置第一组broker-a

\

在worker2上先配置borker-a的master节点。先配置2m-2s-async/broker-a.properties

代码语言:javascript
复制
#所属集群名字,名字一样的节点就在同一个集群内
brokerClusterName=rocketmq-cluster
#broker名字,名字一样的节点就是一组主从节点。
brokerName=broker-a
#brokerid,0就表示是Master,>0的都是表示 Slave
brokerId=0
#nameServer地址,分号分割
namesrvAddr=worker1:9876;worker2:9876;worker3:9876
#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
#Broker 对外服务的监听端口
listenPort=10911
#删除文件时间点,默认凌晨 4点
deleteWhen=04
#文件保留时间,默认 48 小时
fileReservedTime=120
#commitLog每个文件的大小默认1G
mapedFileSizeCommitLog=1073741824
#ConsumeQueue每个文件默认存30W条,根据业务情况调整
mapedFileSizeConsumeQueue=300000
#destroyMapedFileIntervalForcibly=120000
#redeleteHangedFileInterval=120000
#检测物理文件磁盘空间
diskMaxUsedSpaceRatio=88
#存储路径
storePathRootDir=/opt/rocketmq/store
#commitLog 存储路径
storePathCommitLog=/opt/rocketmq/store/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/opt/rocketmq/store/consumequeue
#消息索引存储路径
storePathIndex=/opt/rocketmq/store/index
#checkpoint 文件存储路径
storeCheckpoint=/opt/rocketmq/store/checkpoint
#abort 文件存储路径
abortFile=/opt/rocketmq/store/abort
#限制的消息大小
maxMessageSize=65536
#flushCommitLogLeastPages=4
#flushConsumeQueueLeastPages=2
#flushCommitLogThoroughInterval=10000
#flushConsumeQueueThoroughInterval=60000
#Broker 的角色
#- ASYNC_MASTER 异步复制Master
#- SYNC_MASTER 同步双写Master
#- SLAVE
brokerRole=ASYNC_MASTER
#刷盘方式
#- ASYNC_FLUSH 异步刷盘
#- SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH
#checkTransactionMessageEnable=false
#发消息线程池数量
#sendMessageThreadPoolNums=128
#拉消息线程池数量
#pullMessageThreadPoolNums=128

该节点对应的从节点在worker3上。修改2m-2s-async/broker-a-s.properties 只需要修改brokerId和brokerRole

代码语言:javascript
复制
#所属集群名字,名字一样的节点就在同一个集群内
brokerClusterName=rocketmq-cluster
#broker名字,名字一样的节点就是一组主从节点。
brokerName=broker-a
#brokerid,0就表示是Master,>0的都是表示 Slave
brokerId=1
#nameServer地址,分号分割
namesrvAddr=worker1:9876;worker2:9876;worker3:9876
#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
#Broker 对外服务的监听端口
listenPort=11011
#删除文件时间点,默认凌晨 4点
deleteWhen=04
#文件保留时间,默认 48 小时
fileReservedTime=120
#commitLog每个文件的大小默认1G
mapedFileSizeCommitLog=1073741824
#ConsumeQueue每个文件默认存30W条,根据业务情况调整
mapedFileSizeConsumeQueue=300000
#destroyMapedFileIntervalForcibly=120000
#redeleteHangedFileInterval=120000
#检测物理文件磁盘空间
diskMaxUsedSpaceRatio=88
#存储路径
storePathRootDir=/opt/rocketmq/storeSlave
#commitLog 存储路径
storePathCommitLog=/opt/rocketmq/storeSlave/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/opt/rocketmq/storeSlave/consumequeue
#消息索引存储路径
storePathIndex=/opt/rocketmq/storeSlave/index
#checkpoint 文件存储路径
storeCheckpoint=/opt/rocketmq/storeSlave/checkpoint
#abort 文件存储路径
abortFile=/opt/rocketmq/storeSlave/abort
#限制的消息大小
maxMessageSize=65536
#flushCommitLogLeastPages=4
#flushConsumeQueueLeastPages=2
#flushCommitLogThoroughInterval=10000
#flushConsumeQueueThoroughInterval=60000
#Broker 的角色
#- ASYNC_MASTER 异步复制Master
#- SYNC_MASTER 同步双写Master
#- SLAVE
brokerRole=SLAVE
#刷盘方式
#- ASYNC_FLUSH 异步刷盘
#- SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH
#checkTransactionMessageEnable=false
#发消息线程池数量
#sendMessageThreadPoolNums=128
#拉消息线程池数量
#pullMessageThreadPoolNums=128

\

2、配置第二组Broker-b

这一组broker的主节点在worker3上,所以需要配置worker3上的config/2m-2s-async/broker-b.properties

代码语言:javascript
复制
#所属集群名字,名字一样的节点就在同一个集群内
brokerClusterName=rocketmq-cluster
#broker名字,名字一样的节点就是一组主从节点。
brokerName=broker-b
#brokerid,0就表示是Master,>0的都是表示 Slave
brokerId=0
#nameServer地址,分号分割
namesrvAddr=worker1:9876;worker2:9876;worker3:9876
#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
#Broker 对外服务的监听端口
listenPort=10911
#删除文件时间点,默认凌晨 4点
deleteWhen=04
#文件保留时间,默认 48 小时
fileReservedTime=120
#commitLog每个文件的大小默认1G
mapedFileSizeCommitLog=1073741824
#ConsumeQueue每个文件默认存30W条,根据业务情况调整
mapedFileSizeConsumeQueue=300000
#destroyMapedFileIntervalForcibly=120000
#redeleteHangedFileInterval=120000
#检测物理文件磁盘空间
diskMaxUsedSpaceRatio=88
#存储路径
storePathRootDir=/opt/rocketmq/store
#commitLog 存储路径
storePathCommitLog=/opt/rocketmq/store/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/opt/rocketmq/store/consumequeue
#消息索引存储路径
storePathIndex=/opt/rocketmq/store/index
#checkpoint 文件存储路径
storeCheckpoint=/opt/rocketmq/store/checkpoint
#abort 文件存储路径
abortFile=/opt/rocketmq/store/abort
#限制的消息大小
maxMessageSize=65536
#flushCommitLogLeastPages=4
#flushConsumeQueueLeastPages=2
#flushCommitLogThoroughInterval=10000
#flushConsumeQueueThoroughInterval=60000
#Broker 的角色
#- ASYNC_MASTER 异步复制Master
#- SYNC_MASTER 同步双写Master
#- SLAVE
brokerRole=ASYNC_MASTER
#刷盘方式
#- ASYNC_FLUSH 异步刷盘
#- SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH
#checkTransactionMessageEnable=false
#发消息线程池数量
#sendMessageThreadPoolNums=128
#拉消息线程池数量
#pullMessageThreadPoolNums=128

\

然后他对应的slave在worker2上,修改work2上的 conf/2m-2s-async/broker-b-s.properties

代码语言:javascript
复制
#所属集群名字,名字一样的节点就在同一个集群内
brokerClusterName=rocketmq-cluster
#broker名字,名字一样的节点就是一组主从节点。
brokerName=broker-b
#brokerid,0就表示是Master,>0的都是表示 Slave
brokerId=1
#nameServer地址,分号分割
namesrvAddr=worker1:9876;worker2:9876;worker3:9876
#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
#Broker 对外服务的监听端口
listenPort=11011
#删除文件时间点,默认凌晨 4点
deleteWhen=04
#文件保留时间,默认 48 小时
fileReservedTime=120
#commitLog每个文件的大小默认1G
mapedFileSizeCommitLog=1073741824
#ConsumeQueue每个文件默认存30W条,根据业务情况调整
mapedFileSizeConsumeQueue=300000
#destroyMapedFileIntervalForcibly=120000
#redeleteHangedFileInterval=120000
#检测物理文件磁盘空间
diskMaxUsedSpaceRatio=88
#存储路径
storePathRootDir=/opt/rocketmq/storeSlave
#commitLog 存储路径
storePathCommitLog=/opt/rocketmq/storeSlave/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/opt/rocketmq/storeSlave/consumequeue
#消息索引存储路径
storePathIndex=/opt/rocketmq/storeSlave/index
#checkpoint 文件存储路径
storeCheckpoint=/opt/rocketmq/storeSlave/checkpoint
#abort 文件存储路径
abortFile=/opt/rocketmq/storeSlave/abort
#限制的消息大小
maxMessageSize=65536
#flushCommitLogLeastPages=4
#flushConsumeQueueLeastPages=2
#flushCommitLogThoroughInterval=10000
#flushConsumeQueueThoroughInterval=60000
#Broker 的角色
#- ASYNC_MASTER 异步复制Master
#- SYNC_MASTER 同步双写Master
#- SLAVE
brokerRole=SLAVE
#刷盘方式
#- ASYNC_FLUSH 异步刷盘
#- SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH
#checkTransactionMessageEnable=false
#发消息线程池数量
#sendMessageThreadPoolNums=128
#拉消息线程池数量
#pullMessageThreadPoolNums=128

这样broker就配置完成了。

需要注意的配置项:

1、同一机器上两个实例的store目录不能相同,否则会报错 Lock failed,MQ already started

2、同一机器上两个实例的listenPort也不能相同。否则会报端口占用的错,nameserver不需要进行配置,直接启动就行。这也看出nameserver是无状态的。

3、其他的配置项参见《RcoketMQ全部配置表.pdf》

\

7、启动RocketMQ

\

启动就比较简单了,直接调用bin目录下的脚本就行。只是启动之前要注意看下他们的JVM内存配置,默认的配置都比较高。

1、先启动nameServer。

修改三个节点上的bin/runserver.sh,调整里面的jvm内存配置。找到下面这一行调整下内存

代码语言:javascript
复制
JAVA_OPT="${JAVA_OPT} -server -Xms512m -Xmx512m -Xmn256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"

\

直接在三个节点上启动nameServer。

代码语言:javascript
复制
nohup /opt/rocketmq/bin/mqnamesrv > /opt/rocketmq/nameServer.log 2>&1 &

\

启动完成后,在nohup.out里看到这一条关键日志就是启动成功了。

\

Java HotSpot(TM) 64-Bit Server VM warning: Using the DefNew young collector with the CMS collector is deprecated and will likely be removed in a future release Java HotSpot(TM) 64-Bit Server VM warning: UseCMSCompactAtFullCollection is deprecated and will likely be removed in a future release. The Name Server boot success. serializeType=JSON

\

使用jps指令可以看到一个NamesrvStartup进程。

\

这里也看到,RocketMQ在runserver.sh中是使用的CMS垃圾回收期,而在runbroker.sh中使用的是G1垃圾回收期。

\

2、再启动broker

\

启动broker是使用的mqbroker指令,只是注意启动broker时需要通过-c 指定对应的配置文件。

\

在worker2上启动broker-a的master节点和broker-b的slave节点

代码语言:javascript
复制
nohup /opt/rocketmq/bin/mqnamesrv -c /opt/rocketmq/conf/2m-2s-async/broker-a.properties &
nohup /opt/rocketmq/bin/mqnamesrv -c /opt/rocketmq/conf/2m-2s-async/broker-b-s.properties &

\

在work3上启动broker-b的master节点和broker-a的slave节点

代码语言:javascript
复制
nohup /opt/rocketmq/bin/mqbroker -c /opt/rocketmq/conf/2m-2s-async/broker-b.properties &
nohup /opt/rocketmq/bin/mqbroker -c /opt/rocketmq/conf/2m-2s-async/broker-a-s.properties &

启动slave时,如果遇到报错 Lock failed,MQ already started ,那是因为有多个实例共用了同一个storePath造成的,这时就需要调整store的路径。

\

3、启动状态检查

\

使用jps指令,能看到一个NameSrvStartup进程和两个BrokerStartup进程。

\

nohup.out中也有启动成功的日志。

\

对应的日志文件:

代码语言:javascript
复制
查看nameServer日志
tail -500f /opt/rocketmq/nameServer.log
查看broker日志
tail -500f /opt/rocketmq/broker.log

\

4、测试mqadmin管理工具

RocketMQ的源代码中并没有为我们提供类似于Nacos或者RabbitMQ那样的控制台,只提供了一个mqadmin指令来管理RocketMQ,命令在bin目录下。使用方式是 ./mqadmin {command} {args}\

1、几乎所有指令都需要通过-n参数配置nameServer地址,格式为ip:port

2、几乎所有执行都可以通过-h参数获得帮助

3、当既有Broker地址(-b)又有集群名称clustername(-c)配合项,则优先以Broker地址执行指令。如果不配置Broker地址,则对集群中所有主机执行指令。

5、命令行快速验证

在RocketMQ的安装包中,提供了一个tools.sh工具可以用来在命令行快速验证RocketMQ服务。我们在worker2上进入RocketMQ的安装目录:

发送消息:默认会发1000条消息

代码语言:javascript
复制
bin/tools.sh org.apache.rocketmq.example.quickstart.Producer 

接收消息:

代码语言:javascript
复制
bin/tools.sh  org.apache.rocketmq.example.quickstart.Consumer 

注意,这是官方提供的Demo,但是官方的源码中,这两个类都是没有指定nameServer的,所以运行会有点问题。要指定NameServer地址,可以配置一个环境变量NAMESRV_ADDR,这样默认会读取这个NameServer地址。可以配到.bash_profile里或者直接临时指定。

代码语言:javascript
复制
export NAMESRV_ADDR='worker1:9876;worker2:9876;worker3:9876' 

然后就可以正常执行了。

这个NameServer地址的读取方式见源码中org.apache.rocketmq.common.utils.NameServerAddressUtils

代码语言:javascript
复制
    public static String getNameServerAddresses() {
        return System.getProperty("rocketmq.namesrv.addr", System.getenv("NAMESRV_ADDR"));
    }

这个方法就是在DefaultMQProducer中默认的设置NameServer地址的方式,这个rokcetmq.namesrv.addr属性可以在java中使用System.setproperties指定,也可以在SpringBoot中配到配置文件里。

这个tools.sh就封装了一个简单的运行RocketMQ的环境,可以运行源码中的其他示例,然后自己的例子也可以放到RocketMQ的lib目录下去执行。

8、搭建管理控制台
jar包运行

RocketMQ源代码中并没有提供控制台,但是有一个Rocket的社区扩展项目中提供了一个控制台

官网地址:https://github.com/apache/rocketmq-externals

gitCode地址:https://gitcode.net/java_wxid/rocketmq-externals-master

下载下来后,进入其中的rocket-console目录,使用maven进行编译

代码语言:javascript
复制
mvn clean package -Dmaven.test.skip=true 

编译完成后,获取target下的jar包,就可以直接执行。但是这个时候要注意,在这个项目的application.properties中需要指定nameserver的地址。默认这个属性是空的。

那我们可以在jar包的当前目录下增加一个application.properties文件,覆盖jar包中默认的一个属性:

代码语言:javascript
复制
rocketmq.config.namesrvAddr=worker1:9876;worker2:9876;worker3:9876 

如果不是集群,只需要配置一个即可

代码语言:javascript
复制
rocketmq.config.namesrvAddr=ip:9876 

然后执行:

代码语言:javascript
复制
java -jar rocketmq-console-ng-1.0.1.jar 

启动完成后,可以访问 http://ip:端口看到管理页面

在管理页面的右上角可以选择语言。

docker镜像运行
代码语言:javascript
复制
vim /opt/rocketmq/conf/broker.conf

增加两行配置:\

代码语言:javascript
复制
namesrvAddr=139.224.233.121:9876
brokerIP1=139.224.233.121

这里我使用的是docker进行直接拉取镜像运行的方式,二行命令就搞定了

代码语言:javascript
复制
docker pull styletang/rocketmq-console-ng
代码语言:javascript
复制
docker run --name rocketmq -d -e "JAVA_OPTS=-Drocketmq.namesrv.addr=139.224.233.121:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false -Duser.timezone='Asia/Shanghai'" -v /etc/localtime:/etc/localtime -p 8080:8080 -t styletang/rocketmq-console-ng
9、Dleger高可用集群搭建

通过这种方式,我们搭建了一个主从结构的RocketMQ集群,但是我们要注意,这种主从结构是只做数据备份,没有容灾功能的。也就是说当一个master节点挂了后,slave节点是无法切换成master节点继续提供服务的。注意这个集群至少要是3台,允许少于一半的节点发生故障。

如果slave挂了,对集群的影响不会很大,因为slave只是做数据备份的。但是影响也是会有的,例如,当消费者要拉取的数据量比较大时,RocketMQ有一定的机制会优先保证Master节点的性能,只让Master节点返回一小部分数据,而让其他部分的数据从slave节点去拉取。另外,需要注意,Dleger会有他自己的CommitLog机制,也就是说,使用主从集群累计下来的消息,是无法转移到Dleger集群中的。

而如果要进行高可用的容灾备份,需要采用Dledger的方式来搭建高可用集群。注意,这个Dledger需要在RocketMQ4.5以后的版本才支持,我们使用的4.7.1版本已经默认集成了dledger。

搭建方法

要搭建高可用的Broker集群,我们只需要配置conf/dleger下的配置文件就行。

这种模式是基于Raft协议的,是一个类似于Zookeeper的paxos协议的选举协议,也是会在集群中随机选举出一个leader,其他的就是follower。只是他选举的过程跟paxos有点不同。Raft协议基于随机休眠机制的,选举过程会比paxos相对慢一点。

首先:我们同样是需要修改runserver.sh和runbroker.sh,对JVM内存进行定制。

然后:我们需要修改conf/dleger下的配置文件。 跟dleger相关的几个配置项如下:

配置完后,同样是使用 nohup bin/mqbroker -c $conf_name & 的方式指定实例文件。

在bin/dleger下可以创建一个fast-try.sh脚本,可以用来在本地启动三个RocketMQ实例,搭建一个高可用的集群,读取的就是conf/dleger下的broker-no.conf,broker-n1.conf和broker-n2.conf。使用这个脚本同样要注意定制下JVM内存,他给每个实例默认定制的是1G内存,虚拟机肯定是不够的。

这种单机三实例的集群搭建完成后,可以使用 bin/mqadmin clusterList -n worker1.conf的方式查看集群状态。

单机状态下一般一次主从切换需要大概10S的时间。

10、调整系统参数

到这里,我们的整个RocketMQ的服务就搭建完成了。但是在实际使用时,我们说RocketMQ的吞吐量、性能都很高,那要发挥RocketMQ的高性能,还需要对RocketMQ以及服务器的性能进行定制

1、配置RocketMQ的JVM内存大小:

之前提到过,在runserver.sh中需要定制nameserver的内存大小,在runbroker.sh中需要定制broker的内存大小。这些默认的配置可以认为都是经过检验的最优化配置,但是在实际情况中都还需要根据服务器的实际情况进行调整。这里以runbroker.sh中对G1GC的配置举例,在runbroker.sh中的关键配置:

代码语言:javascript
复制
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的频率,但是避免了垃圾对象过多,一次垃圾回收时间太长的问题。

然后,后面定制了GC的日志文件,确定GC日志文件的地址、打印的内容以及控制每个日志文件的大小为30M并且只保留5个文件。这些在进行性能检验时,是相当重要的参考内容。

2、RocketMQ的其他一些核心参数

例如在conf/dleger/broker-n0.conf中有一个参数:sendMessageThreadPoolNums=16。这一个参数是表明RocketMQ内部用来发送消息的线程池的线程数量是16个,其实这个参数可以根据机器的CPU核心数进行适当调整,例如如果你的机器核心数超过16个,就可以把这个参数适当调大。

3、Linux内核参数定制

我们在部署RocketMQ的时候,还需要对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。

这些参数在CentOS7中的配置文件都在 /proc/sys/vm目录下。

RocketMQ的bin目录下有个os.sh里面设置了RocketMQ建议的系统内核参数,可以根据情况进行调整。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-01-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • RocketMQ集群架构
    • 1、RocketMQ集群中的各个角色
      • 2、RocketMQ集群搭建
        • 1、机器环境
        • 2、创建用户
        • 3、系统配置
        • 4、安装java
        • 5、安装RocketMQ
        • 6、配置RocketMQ集群
        • 7、启动RocketMQ
        • 8、搭建管理控制台
        • 9、Dleger高可用集群搭建
        • 10、调整系统参数
    相关产品与服务
    文件存储
    文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档