在Metaq1.x/2.x的版本中,分布式协调采用的是Zookeeper,而RocketMQ自己实现了一个NameServer,所以RocketMQ启动时,先启动对应的NameServer。


集群部署方式

RocketMQ部署比较灵活,推荐几种Broker的集群部署方式。

1. 单个Master

很显然,这种方式风险较大,一旦Broker重启或者宕机时,会导致整个服务不可用,不建议线上环境使用。

2. 多Master模式

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

  • 优点:配置简单,单个Master宕机或重启维护对应用无影响,在磁盘配置为RAID10时,即使机器宕机不可恢复情况下,由于RAID10磁盘非常可靠,消息也不会丢(异步刷盘丢失少量消息,同步刷盘一条不丢)。性能最高。
  • 缺点:单台机器宕机期间,这台机器上未被消费的消息在机器恢复之前不可订阅,消息实时性会受到影响。

3. 多Master多Slave模式,异步复制

每个Master配置一个Slave,有多对Master-Slave,HA采用异步复制方式,主备有短暂消息延迟,毫秒级。

  • 优点:即使磁盘损坏,消息丢失的非常少,且消息实时性不会受影响,因为Master宕机后,消费者仍然可以从Slave消费,此过程对应用透明,不需要人工干预。性能同多Master模式几乎一样。
  • 缺点:Master宕机,磁盘损坏情况,会丢失少量消息。

4. 多Master多Slave模式,同步双写

每个Master配置一个Slave,有多对Master-Slave,HA采用同步双写方式,主备都写成功,向应用返回成功。

  • 优点:数据与服务都无单点,Master宕机情况下,消息无延迟,服务可用性与数据可用性都非常高。
  • 缺点:性能比异步复制模式略低,大约低10%左右,发送单个消息的RT会略高。

物理部署结构

以多Master多Slave模式为例,看一下RocketMQ物理部署结构:

RocketMQ物理部署结构

  • NameServer

NameServer是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。

  • Broker

Broker 部署相对复杂,Broker分为Master和Slave,一个Master可以对应多个Slave,但是一个Slave只能对应一个Master,Master与Slave的对应关系通过指定相同的BrokerName,不同的BrokerId来定义,BrokerId为0表示Master,非0表示Slave。Master也可以部署多个。每个Broker与NameServer集群中的所有节点建立长连接,定时注册 Topic 信息到所有 NameServer。

  • Producer

Producer与NameServer集群中的其中一个节点(随机选择)建立长连接,定期从NameServer取Topic路由信息,并向提供Topic服务的Master建立长连接,且定时向Master发送心跳。Producer完全无状态,可集群部署。

  • Consumer

Consumer与NameServer集群中的其中一个节点(随机选择)建立长连接,定期从NameServer取Topic路由信息,并向提供Topic服务的Master、Slave建立长连接,且定时向Master、Slave发送心跳。Consumer既可以从Master订阅消息,也可以从Slave订阅消息,订阅规则由Broker配置决定。


双主集群部署

这里就以双主集群为例,进行搭建。(双主集群会部署搭建,多主或多主多从也自然没啥问题了)

1. 服务器环境

如果条件允许,NameServer和broker分别在单独的机器上部署,我是用自己的电脑建的虚拟机,在虚拟机中部署的,限于自己电脑的配置,NameServer和broker就放在一台机器上了。

序号IP角色模式
1192.168.2.222nameServer1,brokerServer1Master1
1192.168.2.223nameServer2,brokerServer2Master2

2. 配置IP映射

其实是可以不配的,为了部署方便起见,我反正配置了。在下面的文件中配置:

# vi /etc/hosts 
IPNAME
192.168.2.222ocketmq-nameserver-1
192.168.2.222rocketmq-master-1
192.168.2.223rocketmq-nameserver-2
192.168.2.223rocketmq-master-2

3. 上传解压

这里没有用最新版的RocketMQ,而是比较经典的3.2.6版本,两台机器执行相同的操作。
首先上传alibaba-rocketmq-3.2.6.tar.gz文件至/usr/local,然后进行解压。为了操作方便,这里建立了软连接:

# tar -zxvf alibaba-rocketmq-3.2.6.tar.gz -C /usr/local
# mv alibaba-rocketmq alibaba-rocketmq-3.2.6
# ln -s alibaba-rocketmq-3.2.6 rocketmq

4. 创建存储路径

两台机器执行相同的操作:

# mkdir -p rocketmq/store/{commitlog,consumequeue,index}

5. 修改配置文件(替换成以下内容)

两台机器执行相同的操作,并注意,brokerName的值跟配置文件一致:

# vim /usr/local/rocketmq/conf/2m-noslave/broker-a.properties
# vim /usr/local/rocketmq/conf/2m-noslave/broker-b.properties

这里把常用的参数配置基本都列了出来,具体意思在注释里:

#所属集群名字
brokerClusterName=rocketmq-cluster
#broker名字,注意此处不同的配置文件填写的不一样
brokerName=broker-a|broker-b
#0 表示 Master,>0 表示 Slave
brokerId=0
#nameServer地址,分号分割
namesrvAddr=rocketmq-nameserver1:9876;rocketmq-nameserver2: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= /usr/local/rocketmq/store
#commitLog 存储路径
storePathCommitLog= /usr/local/rocketmq/store /commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/usr/local/rocketmq/store/consumequeue
#消息索引存储路径
storePathIndex=/usr/local/rocketmq/store/index
#checkpoint 文件存储路径
storeCheckpoint=/usr/local/rocketmq/store/checkpoint
#abort 文件存储路径
abortFile=/usr/local/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

6. 修改日志配置文件

修改日志配置文件的目录,两台机器执行相同的操作:

# mkdir -p /usr/local/rocketmq/logs
# cd /usr/local/rocketmq/conf && sed -i 's#${user.home}#/usr/local/rocketmq#g' *.xml

7. 修改启动脚本参数

调一下JVM,包括nameserver 和 broker。限于自己机器的配置,参数调小一下。但Rocketmq最少的堆是1g,否则无法启动。两台机器执行相同的操作。
打开一下runbroker配置文件:

# vim /usr/local/rocketmq/bin/runbroker.sh

修改内容如下:

JAVA_OPT="${JAVA_OPT} -server -Xms1g -Xmx1g -Xmn512m -
XX:PermSize=128m -XX:MaxPermSize=320m"

打开一下runserver配置文件:

# vim /usr/local/rocketmq/bin/runserver.sh

修改内容如下:

JAVA_OPT="${JAVA_OPT} -server -Xms1g -Xmx1g -Xmn512m -
XX:PermSize=128m -XX:MaxPermSize=320m"

8. 启动

要先启动namerserver,再启broker,两台机器执行相同的操作。
启动nameserver

# cd /usr/local/rocketmq/bin
# nohup sh mqnamesrv &

启动brokerserver(节点1用的是a.properties,节点2用的是b.properties

# cd /usr/local/rocketmq/bin
# nohup sh mqbroker -c /usr/local/rocketmq/conf/2m-noslave/broker-a.properties >/dev/null 2>&1 &
# netstat -ntlp

用下面命令查看一下

# jps

RocketMQ-jps

可以用下面命令查看一下启动日志:

# tail -f -n 500 /usr/local/rocketmq/logs/rocketmqlogs/broker.log
# tail -f -n 500 /usr/local/rocketmq/logs/rocketmqlogs/namesrv.log

9. 部署管控台

在tomcat中部署rocketmq-console.war,修改WEB-INF/classes/config.properties:

RocketMQ-管控台-config.properties

启动管控台,看一下首页:

RocketMQ-管控台-首页

界面比较简洁,最好进入Topic界面进行mqadmin操作命令:

这里写图片描述

10. 数据清理

首先停一下服务:

# cd /usr/local/rocketmq/bin
# sh mqshutdown broker
# sh mqshutdown namesrv

然后清一下store,但别忘记重新建一下:

# rm -rf /usr/local/rocketmq/store
# mkdir /usr/local/rocketmq/store
# mkdir /usr/local/rocketmq/store/commitlog
# mkdir /usr/local/rocketmq/store/consumequeue
# mkdir /usr/local/rocketmq/store/index

PS:

  • 如果要搭主从,再次重申一遍Master与Slave在配置中的区别

Broker与Slave配对是通过指定相同的brokerName参数来配对,Master的BrokerId 必须是0,Slave的BrokerId必须是大于0的数。另外一个Master下面可以挂载多个Slave,同一Master下的多个Slave 通过指定不同的BrokerId来区分。

  • Broker 重启对客户端的影响

Broker 重启可能会导致正在发往这台机器的的消息发送失败,RocketMQ提供了一种优雅关闭Broker的方法,通过执行以下命令会清除Broker的写权限,过40s后,所有客户端都会更新Broker路由信息,此时再关闭Broker就不会发生发送消息失败的情况,因为所有消息都发往了其他 Broker。

# sh mqadmin wipeWritePerm -b brokerName -n namesrvAddr
  • Master 与Slave的关系

RocketMQ的开源版本,Master宕机,Slave不能切换为Master,这里的Slave不可写,但可读,类似于 Mysql 主备方式。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐