【RocketMQ专题】单点部署、集群部署、Dledger高可用部署

前言

本专题整理了RocketMQ单机部署、集群部署、Dledger高可用集群部署的详细步骤。配合系统参数调优的讲解,能够帮助大家从多个维度去理解RocketMQ的工作原理。


基本介绍

首先简单介绍一下今天的主角:

RocketMQ是阿里巴巴开源的一个消息中间件。早期阿里使用ActiveMQ,但是,当消息开始逐渐增多后,ActiveMQ的IO性能很快达到了瓶颈。

于是,阿里开始关注Kafka。但是Kafka是针对日志收集场景设计的,并发性能并不是很理想。尤其当他的Topic过多时,由于Partition文件也会过多,会严重影响IO性能。

于是阿里才决定自研中间件,最早叫做MetaMQ,后来改名成为RocketMQ。

一开始希望解决的最大问题就是多Topic下的IO性能压力。在阿里内部的不断改进下,RocketMQ开始体现出一些不一样的优势。

RocketMQ的消息吞吐量虽然依然不如Kafka,但是却比RabbitMQ高很多。在阿里内部,RocketMQ集群每天处理的请求数超过5万亿次,支持的核心应用超过3000个。

除了支持Java语言。在RocketMQ的社区,也正在开发GO,Python,Nodejs等语言的客户端。

在这里插入图片描述


下载地址

RocketMQ的官网地址: http://rocketmq.apache.org
github地址是 https://github.com/apache/rocketmq

找到想要安装的版本,点击下载即可
在这里插入图片描述

在本专题中,我们选择的版本为4.9.1版本


工作原理

RocketMQ由以下这几个组件组成:
在这里插入图片描述

  • Producer:消息的发送者,通常是业务系统中的一个功能模块。举例理解:寄件人。
  • Consumer:消息接收者,通常也是业务系统中的一个功能模块。举例理解:收件人。
  • Broker:实际处理消息存储、转发等服务的核心组件。举例理解:邮局。
  • NameServer:管理Broker及路由信息。举例理解:邮政管理系统。

部署前准备

不管是单点还是集群部署,在安装RocketMQ之前都需要确保服务器环境如下:

准备一台CentOS7的Linux机器,快速把RocketMQ给运行起来。我使用的Linux版本如下:

[oper@worker1 jdk1.8]$ uname -a
Linux worker1 3.10.0-1127.el7.x86_64 #1 SMP Tue Mar 31 23:36:51 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

创建一个操作用户用来运行自己的程序,与root用户区分开。使用root用户创建一个oper用户,并给他创建一个工作目录,并设置密码。

[root@worker1 ~]# useradd oper
[root@worker1 ~]# passwd oper
[root@worker1 ~]# mkdir /app
[root@worker1 ~]# chown oper:oper /app

运行RocketMQ需要先安装JDK。由oper用户解压到/app/jdk1.8目录下。

[oper@worker1 tools]$ tar -zxvf jdk-8u171-linux-x64.tar.gz
[oper@worker1 tools]$ mv jdk1.8.0_171/ /app/jdk1.8

配置JAVA环境变量。使用 vi ~/.bash_profile 编辑文件,在下面加入以下内容:

export JAVA_HOME=/app/jdk1.8/
PATH=$JAVA_HOME/bin:$PATH:$HOME/.local/bin:$HOME/bin
export PATH

编辑完成后,执行 source ~/.bash_profile 让环境变量生效。输入 java -version 能查看到以下内容表明JDK安装成功了。

[oper@worker1 ~]$ java -version
java version "1.8.0_171"
Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)

把下载的rocketmq-all-4.9.1-bin-release.zip在本地完成解压,并上传到/app/rocketmq目录。完成后,把rocketmq的bin目录也配置到环境变量当中。

vi ~/.bash_profile ,加入以下内容,并执行 source ~/.bash_profile 让环境变量生效:

export JAVA_HOME=/app/jdk1.8/
export ROCKETMQ_HOME=/app/rocketmq/rocketmq-all-4.9.1-bin-release
PATH=$ROCKETMQ_HOME/bin:$JAVA_HOME/bin:$PATH:$HOME/.local/bin:$HOME/bin
export PATH

这个ROCKETMQ_HOME的环境变量是必须要单独配置的,如果不配置的话,启动NameSever和Broker都会报错。
这个环境变量的作用是用来加载$ROCKETMQ_HOME/conf下的除broker.conf以外的几个配置文件。
所以实际情况中,可以不按这个配置,但是一定要能找到配置文件。


单点部署

NameServer启动

要启动RocketMQ服务,需要先启动NameServer。

RocketMQ默认预设的JVM内存是4G,这是RocketMQ给我们的最佳配置。但是通常我们用虚拟机的话都是不够4G内存的,所以需要调整下JVM内存大小。

修改的方式是直接修改runserver.sh。 用vi runserver.sh编辑这个脚本,在脚本中找到这一行调整内存大小为512M。

JAVA_OPT="${JAVA_OPT} -server -Xms512m -Xmx512m -Xmn256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"

$ROCKETMQ_HOME/bin目录下有个mqadminsrv。直接执行这个脚本就可以启动RocketMQ的NameServer服务。

nohup bin/mqnamesrv &

启动完成后,在nohup.out里看到这一条关键日志就是启动成功了。使用jps指令可以看到有一个NamesrvStartup进程。

Java HotSpot(TM) 64-Bit Server VM warning: Using the DefNew young collectorwith 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

Broker服务搭建

启动Broker的脚本是runbroker.sh。默认预设内存是8G,如果服务器内存不够,同样需要调整下JVM内存。

1、执行 vi runbroker.sh ,找到这一行,进行内存调整。

JAVA_OPT="${JAVA_OPT} -server -Xms512m -Xmx512m"

2、然后我们需要编辑 $ROCKETMQ_HOME/conf/broker.conf,在最下面加入一个配置:

autoCreateTopicEnable=true

使用RocketMQ进行发消息时,必须要指定topic
一般在开发测试环境中会使用默认设置 autoCreateTopicEnable = true
但是这样就会导致topic的设置不容易规范管理,没有统一的审核
生产环境中会讲将该参数改为:autoCreateTopicEnable = false
需要增加topic时就需要在web管理界面上添加即可

3、启动完成后,同样是检查nohup.out日志,有这一条关键日志就标识启动成功了。 使用jps指令可以看到一个BrokerStartup进程。

The broker[worker1, 192.168.232.128:10911] boot success. serializeType=JSON

在观察runserver.sh和runbroker.sh时,我们还可以查看到其他的JVM执行参数。
这些参数都可以进行定制。
我们观察到一个比较有意思的地方。
NameServer使用的是CMS垃圾回收器。
而Broker使用的是G1。


测试客户端

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

首先需要配置一个环境变量$NAMESRV_ADDR指向我们启动的NameServer服务。

export NAMESRV_ADDR='localhost:9876'

然后启动消息生产者发送消息:默认会发1000条消息

bin/tools.sh org.apache.rocketmq.example.quickstart.Producer

我们可以看到发送消息的日志:

.....
SendResult [sendStatus=SEND_OK, msgId=C0A8E88007AC3764951D891CE9A003E7,offsetMsgId=C0A8E88000002A9F00000000000317BF, messageQueue=MessageQueue[topic=TopicTest, brokerName=worker1, queueId=1], queueOffset=249]
14:59:33.418 [NettyClientSelector_1] INFO RocketmqRemoting - closeChannel:close the connection to remote address[127.0.0.1:9876] result: true
14:59:33.423 [NettyClientSelector_1] INFO RocketmqRemoting - closeChannel:close the connection to remote address[192.168.232.128:10911] result: true

这日志中,上面部分就是我们发送的消息的内容。后面两句标识消息生产者正常关闭。

然后启动消息消费者接收消息:

bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer

启动后,可以看到消费到的消息。

......
ConsumeMessageThread_19 Receive New Messages: [MessageExt[brokerName=worker1, queueId=2, storeSize=203, queueOffset=53, sysFlag=0,bornTimestamp=1606460371999, bornHost=/192.168.232.128:43436,storeTimestamp=1606460372000, storeHost=/192.168.232.128:10911,msgId=C0A8E88000002A9F000000000000A7AE, commitLogOffset=42926,bodyCRC=1968636794, reconsumeTimes=0, preparedTransactionOffset=0,toString()=Message{topic='TopicTest', flag=0, properties={MIN_OFFSET=0,MAX_OFFSET=250, CONSUME_START_TIME=1606460450150,UNIQ_KEY=C0A8E88007AC3764951D891CE41F00D4, CLUSTER=DefaultCluster,WAIT=true, TAGS=TagA}, body=[72, 101, 108, 108, 111, 32, 82, 111, 99, 107,101, 116, 77, 81, 32, 50, 49, 50], transactionId='null'}]]

日志中MessageExt后的整个内容就是一条完整的RocketMQ消息。我们要对这个消息的结构有个大概的了解,后面会对这个消息进行深入的理解。

其中比较关键的属性有:brokerName,queueId,msgId,topic,cluster,tags,body,transactionId。

注意:这个Consume指令并不会结束,他会继续挂起,等待消费其他的消息。我们可以使用CTRL+C停止该进程。


关闭RocketMQ服务

要关闭RocketMQ服务可以通过mqshutdown脚本直接关闭

# 1.关闭NameServer
sh bin/mqshutdown namesrv

# 2.关闭Broker
sh bin/mqshutdown broker

Master/Slave集群部署

集群模式介绍

1、多主集群

一个集群无 Slave,全是 Master,例如 2 个 Master 或者 3 个 Master。

  • 优点:配置简单,单个Master宕机或重启维护对应用无影响。
    即使机器宕机不可恢复情况下,也有其他主节点支持写入操作。
    消息也不会丢(异步刷盘丢失少量消息,同步刷盘一条不丢),性能最高。

  • 缺点:单台机器宕机期间,这台机器上未被消费的消息在机器恢复之前不可订阅。
    消息实时性会受到受到影响。

2、双主双从同步

每个 Master 配置一个 Slave,有多对 Master-Slave,HA 采用同步双写方式。

主节点收到消息之后不立马返回给用户,会等从节点复制成功之后再返回发送成功的消息给用户。主备都写成功时,向应用返回成功。

  • 优点:数据与服务都无单点,Master 宕机情况下,消息无延迟,服务可用性与数据可用性、安全性都非常高。

  • 缺点:相比异步复制,性能比异步复制模式略低。客户端接受服务器响应时间更长。可用于消息安全高的场景

3、双主双从异步

每个 Master 配置一个 Slave,有多对 Master-Slave,HA 采用异步复制方式

主节点收到消息之后立马就返回给用户,然后再开一个线程与从节点进行复制。主备有短暂毫秒级消息延迟。

  • 优点:相比同步双写,客户端能更快的接收到服务器的消息,效率较高。

  • 缺点:Master 宕机,磁盘损坏情况,会丢失少量消息,可用于允许消息部分丢失的场景


服务器准备

为了便于观察,这次搭建一个2主2从异步刷盘的集群

准备三台虚拟机,硬盘空间建议大于4G。配置机器名。
下文的描述中,会更多的会关注机器名,而不会太多关注IP地址。

vi /etc/hosts
192.168.232.128 worker1
192.168.232.129 worker2
192.168.232.130 worker3

配置主从集群

把RocketMQ的安装包上传到服务器,预备设计的集群情况如下:

机器名nemaeServer节点部署broker节点部署
worker1nameserver
worker2nameserverbroker-a, broker-b-s
worker3nameserverbroker-b, broker-a-s

配置第一组broker-a

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

#所属集群名字,名字一样的节点就在同一个集群内
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=/app/rocketmq/store
#commitLog 存储路径
storePathCommitLog=/app/rocketmq/store/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/app/rocketmq/store/consumequeue
#消息索引存储路径
storePathIndex=/app/rocketmq/store/index
#checkpoint 文件存储路径
storeCheckpoint=/app/rocketmq/store/checkpoint
#abort 文件存储路径
abortFile=/app/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上。修改config/2m-2s-async/broker-a-s.properties

#所属集群名字,名字一样的节点就在同一个集群内
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=/app/rocketmq/storeSlave
#commitLog 存储路径
storePathCommitLog=/app/rocketmq/storeSlave/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/app/rocketmq/storeSlave/consumequeue
#消息索引存储路径
storePathIndex=/app/rocketmq/storeSlave/index
#checkpoint 文件存储路径
storeCheckpoint=/app/rocketmq/storeSlave/checkpoint
#abort 文件存储路径
abortFile=/app/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-b

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

#所属集群名字,名字一样的节点就在同一个集群内
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=/app/rocketmq/store
#commitLog 存储路径
storePathCommitLog=/app/rocketmq/store/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/app/rocketmq/store/consumequeue
#消息索引存储路径
storePathIndex=/app/rocketmq/store/index
#checkpoint 文件存储路径
storeCheckpoint=/app/rocketmq/store/checkpoint
#abort 文件存储路径
abortFile=/app/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

#所属集群名字,名字一样的节点就在同一个集群内
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=/app/rocketmq/storeSlave
#commitLog 存储路径
storePathCommitLog=/app/rocketmq/storeSlave/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/app/rocketmq/storeSlave/consumequeue
#消息索引存储路径
storePathIndex=/app/rocketmq/storeSlave/index
#checkpoint 文件存储路径
storeCheckpoint=/app/rocketmq/storeSlave/checkpoint
#abort 文件存储路径
abortFile=/app/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主2从的集群配置基本就完成了。搭建过程中需要注意的配置项:

1、同一机器上两个实例的store目录不能相同,否则会报错 Lock failed,MQ already started
2、同一机器上两个实例的listenPort也不能相同。否则会报端口占用的错。nameserver不需要进行配置,直接启动就行。这也看出nameserver是无状态的。
3、如果是多网卡的机器,比如云服务器,那么需要在broker.conf中增加brokerIP属性,指定所在机器的外网网卡地址。


启动RocketMQ

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

1、启动NameServer

与单点部署的步骤相同,修改三个节点上的bin/runserver.sh,调整里面的jvm内存配置。

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


2、启动Broker

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

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

nohup ./mqbroker -c ../conf/2m-2s-async/broker-a.properties &
nohup ./mqbroker -c ../conf/2m-2s-async/broker-b-s.properties &

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

nohup ./mqbroker -c ../conf/2m-2s-async/broker-b.properties &
nohup ./mqbroker -c ../conf/2m-2s-async/broker-a-s.properties &

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


3、启动状态检查

使用jps指令,能看到一个NameSrvStartup进程和两个BrokerStartup进程。nohup.out中也有启动成功的日志。

对应的日志文件:

# 查看nameServer日志
tail -500f ~/logs/rocketmqlogs/namesrv.log
# 查看broker日志
tail -500f ~/logs/rocketmqlogs/broker.log

4、测试mqadmin管理工具

RocketMQ源码中并没有提供管理控制台,只提供了一个mqadmin指令来管理RocketMQ。指令的位置在bin目录下。直接使用该指令就会列出所有支持的命令。

在这里插入图片描述
使用方式都是 mqadmin {command} {args}。 如果有某个指令不会使用,可以使用 mqadmin help {command} 指令查看帮助。


5、命令行快速验证

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

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

bin/tools.sh org.apache.rocketmq.example.quickstart.Producer

接收消息:

bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer

注意,这是官方提供的Demo,但是官方的源码中,这两个类都是没有指定nameServer的,所以运行会有点问题。

要指定NameServer地址,可以配置一个环境变量NAMESRV_ADDR,这样默认会读取这个NameServer地址。可以配到.bash_profile里或者直接临时指定。

export NAMESRV_ADDR='worker1:9876;worker2:9876;worker3:9876'

然后就可以正常执行了。

这个tooles.sh实际上是封装了一个简单的运行RocketMQ的环境,上面指令中指定的Java类,都在lib/rocketmq-example-4.9.1.jar包中。未来如果自己有一些客户端示例,也可以打成jar包放到这个lib目录下,通过tools.sh运行。


搭建管理控制台

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

地址: https://github.com/apache/rocketmq-dashboard

下载下来后,解压并进入对应的目录,使用maven进行编译

mvn clean package -Dmaven.test.skip=true

编译完成后,获取target下的jar包,就可以直接执行。

但是这个时候要注意,在这个项目的application.yml中需要指定nameserver的地址。

默认这个属性是指向本地。如果配置为空,会读取环境变量NAMESRV_ADDR

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

rocketmq:
	config:
		namesrvAddrs:
			- worker1:9876
			- worker2:9876
			- worker3:9876

其他更多配置信息可以参考dashboard源码中的配置文件。

然后执行:

java -jar rocketmq-dashboard-1.0.1-SNAPSHOT.jar

启动完成后,可以访问 http://192.168.232.128:8080 看到管理页面


Dledger高可用集群部署

主从切换

Dledger 作为一个轻量级的 Java Library,它的作用就是将 Raft 有关于算法方面的内容全部抽象掉,开发人员只需要关心业务即可。

在 RocketMQ 4.5 版本之前,RocketMQ 只有 Master/Slave 一种部署方式:
一组 broker 中有一个 Master ,有零到多个Slave,Slave 通过同步复制或异步复制的方式去同步 Master 数据。Master/Slave 部署模式,提供了一定的高可用性。

但这样都 Master/Slave 部署模式,有一定缺陷:
1、比如故障转移方面,如果主节点挂了,还需要人为手动进行重启或者切换,无法自动将一个从节点转换为主节点,缺乏容灾功能。因此,我们希望能有一个新的多副本架构,去解决这个问题。

2、如果slave挂了,对集群的影响不大,因为slave只是做数据备份的。但是影响也是会有的,例如:当消费者要拉取的数据量比较大时,RocketMQ为了保证Master节点的性能,只会让Master节点返回一小部分数据,而让其他部分的数据从slave节点去拉取。

此外,由于Dleger会有他自己的CommitLog机制,也就是说,使用主从集群累计下来的消息,是无法转移到Dleger集群中的,这一点需要格外注意。

源码分析 RocketMQ DLedger 多副本可以参考:
源码分析 RocketMQ DLedger 多副本即主从切换实现原理


搭建方法

为了节约篇幅,我会基于前一章节:Master/Slave集群部署 的基础上进行说明,默认与之相同的集群环境下进行安装。

首先:我们同样是需要修改runserver.shrunbroker.sh,对JVM内存进行定制,准备好主从配置文件。

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

name含义举例
enableDLegerCommitLog是否启动 DLedgertrue
dLegerGroupDLedger Raft Group 的名字,建议和 brokerName 保持一致RaftNode00
dLegerPeersDLedger 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

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

在bin/dleger下有个fast-try.sh,这个脚本是在本地启动三个RocketMQ实例,搭建一个高可用的集群,读取的就是conf/dleger下的broker-n0.confbroker-n1.confbroker-n2.conf

使用这个脚本同样要注意定制下JVM内存,他给每个实例默认定制的是1G内存,虚拟机肯定是不够的。

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


系统参数调优

到这里,我们的整个RocketMQ的服务就搭建完成了。

但是在实际使用时,由于RocketMQ的吞吐量、性能都很高,如果发挥RocketMQ的高性能,还需要对RocketMQ以及服务器的性能进行调优。

1、RocketMQ的JVM内存大小

在之前的部署过程中,我们不止一次的修改过:
1、runserver.sh中定制 nameserver 的内存大小。
2、runbroker.sh中定制broker的内存大小。

这些默认的配置可以认为都是经过检验的最优化配置,但是在实际情况中都还需要根据服务器的实际情况进行调整。

这里以runbroker.sh中对G1GC的配置举例,在runbroker.sh中的关键配置:

JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XXInitiatingHeapOccupancyPercent=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"

1、-XX:+UseG1GC:使用G1垃圾回收器
2、-XX:G1HeapRegionSize=16m:将G1的region块大小设为16M
3、-XX:G1ReservePercent:在G1的老年代中预留25%空闲内存,这个默认值是10%,RocketMQ把这个参数调大了。
4、-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内核参数进行一定的定制。例如:

1、 ulimit:需要进行大量的网络通信和磁盘IO。
2、 vm.extra_free_kbytes:告诉VM在后台回收(kswapd)启动的阈值与直接回收(通过分配进程)的阈值之间保留额外的可用内存。RocketMQ使用此参数来避免内存分配中的长延迟。(与具体内核版本相关)
3、 vm.min_free_kbytes:如果将其设置为低于1024KB,将会巧妙的将系统破坏,并且系统在高负载下容易出现死锁。
4、 vm.max_map_count:限制一个进程可能具有的最大内存映射区域数。RocketMQ将使用mmap加载CommitLog和ConsumeQueue,因此建议将为此参数设置较大的值。
5、 vm.swappiness,定义内核交换内存页面的积极程度。较高的值会增加攻击性,较低的值会减少交换量。建议将值设置为10来避免交换延迟。
6、 File descriptor limits:RocketMQ需要为文件(CommitLog和ConsumeQueue)和网络连接打开文件描述符。我们建议设置文件描述符的值为655350。

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

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


以上就是帖子的全部内容啦,关注我,我会定期更新,期待与你的共同进步!

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值