【部署有格调】【消息中间件】RocketMQ单机/集群篇

2,004 阅读11分钟
作者 日期 版本号
元公子 2019-12-14 v1.0.0

你知道的越少,你不知道的就越少

没有朋友的点赞,就没法升级打怪

一、闲话

RocketMQ是阿里出品的消息中间件,是一个分布式消息传递和流平台,具有低延迟,高性能和可靠性,万亿级容量和灵活的可伸缩性。。。(这个必须要登记到阅读源码的延迟队列中)

先通过官方对于软件架构的讲解,了解软件用到了哪些角色。带你飞地址,通过谷歌翻译还是比较好懂的。。。

由于部署时,会用到其中的概念,这里简单描述下我的理解。

  • NameServer :理解为Leader,默认端口9876。集群时需启动多个该服务,他们之间互不通信。

    主要功能描述:接收客户端的请求(开发项目中的配置信息,就是这位的地址和端口号信息)、管理Broker(通过心跳,不是眼神),以及接收Broker的路由信息,并每个都记录全量的路由信息。

  • Broker Server:理解为NameServer的Follower,也是RocketMQ的核心角色,默认端口10911。集群时需启动多个该服务,她们之间也是互不通信。但在部署HA Service(高可用)时,Broker又分为Master Broker和Slave Broker两种角色,她们之间是数据同步。

    主要功能描述:接收客户端的请求,管理生产者和消费者客户端,管理消息(含物理存储)。

  • Producer和Consumer:生产者和消费者。在部署时,我们不用关心它。应用于开发项目中,生产消息和消费消息的角色。

    所以我们部署时,请留意只有NameServer和Broker Server这两个概念。

二、下载安装包

​ 官方地址:安装文档4.6.0下载地址

​ 下载最新版软件:rocketmq-all-4.6.0-bin-release.zip

三、系统环境检查/准备

  • Java jdk1.8以上环境
  • 示例使用Centos7操作系统
  • 不是女司机,就要全程使用root用户
  • 高能提醒如客官使用非root用户,考虑到权限方面,需把文章中涉及到/var这类根级别的目录,调整为用户home目录,又或者修改目录权限
  • unzip zip指令,安装方式:yum install -y unzip zip
  • 域名映射方式请参考其它文章扩展内容章节

四、单机

​ 此章节主要讲述一个NameServer和一个Broker服务在一台机器上安装。

1.选择安装目录(在/soft文件夹放置工具软件,或者按您意思来)

解压缩

[root@dev /soft]# unzip rocketmq-all-4.6.0-bin-release.zip 

创建软连接,便于后续的软件升级或多版本切换

[root@dev /soft]# ln -s rocketmq-all-4.6.0-bin-release rocketmq

2.设置环境变量

文件最底部追加以下内容,ROCKETMQ_HOME变量名尽量不要修改,因为软件bin目录下的脚本会使用到此名称的环境变量。

[root@dev /soft]# vi /etc/profile
export ROCKETMQ_HOME=/soft/rocketmq
export PATH=$PATH:$ROCKETMQ_HOME/bin
执行保存: Esc :wq
[root@dev /soft]# source /etc/profile

3.简单启动摸摸底

# 启动 NameServer
[root@dev /soft]# mqnamesrv
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
# 表示启动成功,ctrl + c 退出

# 启动 Broker
[root@dev /soft]# mqbroker
Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000005c0000000, 8589934592, 0) failed; error='Cannot allocate memory' (errno=12)
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 8589934592 bytes for committing reserved memory.
# An error report file with more information is saved as:
# /soft/hs_err_pid127774.log
# 我哔哔哔,内存不够啊

4.找点东西改改

  1. JVM参数

NameServer和Broker启动的默认JVM参数有些大,如果是非生产环境,可调小些。

NameServer:通过bin/mqnamesrv脚本,了解到使用bin/runserver.sh来设置JVM,所以来盘她。

找到设置-Xms的地方,并注释该行,调整为以下所示。(看此配置,JDK要用1.8以上)

[root@dev /soft/rocketmq/bin]# vi runserver.sh
#JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
JAVA_OPT="${JAVA_OPT} -server -Xms128m -Xmx128m -Xmn32m -XX:MetaspaceSize=32m -XX:MaxMetaspaceSize=64m"
执行保存: Esc :wq

Broker:通过bin/mqbroker脚本,了解到使用bin/runbroker.sh来设置JVM,所以继续盘。

找到设置-Xms的地方,并注释该行,调整为以下所示。

[root@dev /soft/rocketmq/bin]# vi runbroker.sh
#JAVA_OPT="${JAVA_OPT} -server -Xms8g -Xmx8g -Xmn4g"
JAVA_OPT="${JAVA_OPT} -server -Xms128m -Xmx128m -Xmn32m"
执行保存: Esc :wq
  1. 日志路径

默认路径为当前启动用户的主目录${user.home},可按实际调整存储路径。(其实调了也麻烦,日后更新时还要记住恢复)

NameServer日志:conf/logback_namesrv.xml,找到内容configuration行,在下面定义个同名的日志路径变量替换。日志路径目录会在服务启动时,自动创建。

[root@dev /soft/rocketmq/conf]# vi logback_namesrv.xml
<configuration>
     <property name="user.home" value="/var/rocketmq" />
执行保存: Esc :wq

Broker日志:conf/logback_broker.xml,同上操作。

[root@dev /soft/rocketmq/conf]# vi logback_broker.xml
<configuration>
     <property name="user.home" value="/var/rocketmq" />
执行保存: Esc :wq
  1. 调整Broker默认指定的NameServer的地址(如果都安装在一台机器上可不更改)

首先,把conf/broker.conf 复制一份以作备份,然后在文件底部增加一行namesrvAddr。(IP地址也建议变成域名映射)

[root@dev /soft/rocketmq/conf]# cp broker.conf broker.conf.bak
[root@dev /soft/rocketmq/conf]# vi broker.conf
# 参考行flushDiskType = ASYNC_FLUSH
namesrvAddr=127.0.0.1:9876

Broker启动时,携带-c参数,指定配置文件路径。

[root@dev /soft/rocketmq]# mqbroker -c /soft/rocketmq/conf/broker.conf

五、集群

此章节主要讲述NameServer和Broker的多节点集群。为了增加难度,准备在一台机器上部署集群。

NameServer集群就是启动多个NameServer服务,Broker集群又分为多个Master,多Master多Slave-异步复制和同步双写三种模式。Slave 备份来自Master的消息,不接收客户端的消息写入,可以消费消息。异步和同步模式区别就是Master在写入消息后,在什么时机来反馈给客户端响应信息。

  • 多个Master,无Slave

    如果其中一台故障,那这台机器上未被消费的消息在其恢复之前将无法被订阅消费。

  • 多Master多Slave-异步复制(参数控制:brokerRole=ASYNC_MASTER)

    异步模式,只要Master写入成功,立即反馈给客户端写成功状态,同时异步写入Slave。主备之间存在短暂的消息延迟。

  • 多Master多Slave-同步双写(参数控制:brokerRole=SYNC_MASTER)

    Master和Slave均写入成功后,才反馈给客户端写成功状态。

另外,这里再关注下消息写入方式的参数flushDiskType,异步刷盘和同步刷盘。

  • 异步刷盘(flushDiskType=ASYNC_FLUSH)

    消息只要被写入到内存后,就反馈给客户端写成功状态。待内存里的消息量积累到一定程度时,统一触发写磁盘操作,快速写入。

  • 同步刷盘(flushDiskType=SYNC_FLUSH)

    消息确认已被写入磁盘后,才反馈给客户端写成功状态。

    官方也提供了这三种模式的默认Broker配置,放在conf目录下:2m-noslave(2个Master)、2m-2s-async(异步复制,2个master,每个master对应1个slave)、2m-2s-sync(同步双写,2个master,每个master对应1个slave)。

这里思考了下要如何写,才能达到全场景覆盖的效果。最终结果是选择把集群部署都放在一台机器上来讲解,毕竟一台的话要比多台考虑的内容会多些,比如端口冲突以及文件目录等情境。但有条件的话,还是每个节点部署一台,毕竟集群的初衷就是最大程度防止单点故障以及提升整体性能吧。

好了,要开始单机部署集群之旅了。我们的集群目标是2个NameServer,4个Broker(2个Master,2个Slave,每个master对应1个slave,异步复制),使用官方配置2m-2s-async扩展讲解。

NameServer集群

  1. 准备配置文件

​ 主要重点是解决端口冲突问题,通过NameServer的配置文件解决。首先,我们先创建存放集群配置的总文件夹以及NameServer配置文件。

# 在用户根目录下,创建集群配置文件夹
[root@dev /soft/rocketmq]# mkdir -p ~/rocketmq/cluster
# 创建两个NameServer的配置文件
[root@dev /soft/rocketmq]# touch ~/rocketmq/cluster/nameserver-a.properties
[root@dev /soft/rocketmq]# touch ~/rocketmq/cluster/nameserver-b.properties

nameserver-a.properties

[root@dev /soft/rocketmq]# vi ~/rocketmq/cluster/nameserver-a.properties
listenPort=9876
# 主目录,这里修改主用于指定所使用的日志文件
rocketmqHome=/root/rocketmq/cluster/nameserver-a
执行保存: Esc :wq

nameserver-b.properties

[root@dev /soft/rocketmq]# vi ~/rocketmq/cluster/nameserver-b.properties
listenPort=9877
rocketmqHome=/root/rocketmq/cluster/nameserver-b
执行保存: Esc :wq
  1. 创建rocketmqHome路径,并考入日志配置文件,使每个NameServer服务生成不同的日志文件。(多个同类型的节点,在启动时会写入相同名称的日志文件,存在一定的干扰)

nameserver-a 日志

[root@dev /soft/rocketmq]# mkdir -p ~/rocketmq/cluster/nameserver-a/conf
[root@dev /soft/rocketmq]# cp ${ROCKETMQ_HOME}/conf/logback_namesrv.xml ~/rocketmq/cluster/nameserver-a/conf/
[root@dev /soft/rocketmq]# vi ~/rocketmq/cluster/nameserver-a/conf/logback_namesrv.xml
<configuration>
     <property name="user.home" value="/var/rocketmq/nameserver-a" />
执行保存: Esc :wq

nameserver-b 日志

[root@dev /soft/rocketmq]# mkdir -p ~/rocketmq/cluster/nameserver-b/conf
[root@dev /soft/rocketmq]# cp ${ROCKETMQ_HOME}/conf/logback_namesrv.xml ~/rocketmq/cluster/nameserver-b/conf/
[root@dev /soft/rocketmq]# vi ~/rocketmq/cluster/nameserver-b/conf/logback_namesrv.xml
<configuration>
     <property name="user.home" value="/var/rocketmq/nameserver-b" />
执行保存: Esc :wq
  1. 启动
[root@dev /soft/rocketmq]# nohup mqnamesrv -c ~/rocketmq/cluster/nameserver-a.properties >/dev/null 2>&1 &
[root@dev /soft/rocketmq]# nohup mqnamesrv -c ~/rocketmq/cluster/nameserver-b.properties >/dev/null 2>&1 &
[root@dev ~]# jps
35538 Jps
35401 NamesrvStartup
35454 NamesrvStartup
[root@dev /soft/rocketmq]# tail -f /var/rocketmq/nameserver-a/logs/rocketmqlogs/namesrv.log 
[root@dev /soft/rocketmq]# tail -f /var/rocketmq/nameserver-b/logs/rocketmqlogs/namesrv.log 

其它关联指令:

  • 查看NameServer所有参数:mqnamesrv -p

Broker集群

  1. 准备配置文件

从conf/2m-2s-async拷贝配置文件到集群配置文件夹。

[root@dev /soft/rocketmq]# cp ${ROCKETMQ_HOME}/conf/2m-2s-async/* ~/rocketmq/cluster/

一起看看Broker配置,估计是要改改,例如端口号,相关路径,以及指定连接NameServer等信息。

broker-a.properties,第一个Master Broker

[root@dev /soft/rocketmq]# vi ~/rocketmq/cluster/broker-a.properties
# ============默认的参数============
# 默认集群名,如果一个集群Broker太多,则可以新增一个集群名,使其后续扩展的Broker连接到另一个集群。
brokerClusterName=DefaultCluster
# broker名称,如果是slave,保存于master一致。如果同属master,则不能一致。
brokerName=broker-a
# broker序号,如果是master,则为0.如果是slave,则1、2、3依序递增。
brokerId=0
# 删除过期文件时间点,默认是每天凌晨4点。默认每个文件的过期时间为72小时,不管文件上的消息是否被全部消费。
deleteWhen=04
# 文件的过期时间,默认不指定为72,官方配置文件修改为48,单位是小时。
fileReservedTime=48
# broker角色。SYNC_MASTER(同步双写),ASYNC_MASTER(异步复制),SLAVE(备份节点)
brokerRole=ASYNC_MASTER
# 刷盘方式:ASYNC_FLUSH(异步刷盘),SYNC_FLUSH(同步刷盘)
flushDiskType=ASYNC_FLUSH
# ============以下新增============
# broker端口。如在同机器,不管是master,还是slave,都不能一样。
# 一个Broker会占用三个端口,以及设置端口号的+1和-2。同机器安装时要留意,至少以4步长递增设置
listenPort=10911
# 指定连接的NameServer,多个以英文;分隔。IP地址最好用域名映射替换,少一些变更机器的烦恼。
namesrvAddr=192.168.0.215:9876;192.168.0.215:9877
# 存储消息的根目录
storePathRootDir=/var/rocketmq/broker-a/store
# commitLog存储路径
storePathCommitLog=/var/rocketmq/broker-a/store/commitlog
# 主目录,这里修改主用于指定所使用的日志文件,会读取该目录下conf文件夹下的日志文件。如果不设置,会读取ROCKETMQ_HOME环境变量的文件夹下conf文件夹下的日志文件
rocketmqHome=/root/rocketmq/cluster/broker-a
# broker机器IP地址,如使用多网卡,而且IP需要手工指定的话可设置
#brokerIP1=192.168.0.215
执行保存: Esc :wq

broker-a-s.properties,第一个Master Broker的Slave节点

[root@dev /soft/rocketmq]# vi ~/rocketmq/cluster/broker-a-s.properties
# ============默认的参数============
brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=1
deleteWhen=04
fileReservedTime=48
brokerRole=SLAVE
flushDiskType=ASYNC_FLUSH
# ============以下新增============
listenPort=10915
namesrvAddr=127.0.0.1:9876;127.0.0.1:9877
storePathRootDir=/var/rocketmq/broker-a-s/store
storePathCommitLog=/var/rocketmq/broker-a-s/store/commitlog
rocketmqHome=/root/rocketmq/cluster/broker-a-s
执行保存: Esc :wq

broker-b.properties,第二个Master Broker

[root@dev /soft/rocketmq]# vi ~/rocketmq/cluster/broker-b.properties
# ============默认的参数============
brokerClusterName=DefaultCluster
brokerName=broker-b
brokerId=0
deleteWhen=04
fileReservedTime=48
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH
# ============以下新增============
listenPort=10919
namesrvAddr=127.0.0.1:9876;127.0.0.1:9877
storePathRootDir=/var/rocketmq/broker-b/store
storePathCommitLog=/var/rocketmq/broker-b/store/commitlog
rocketmqHome=/root/rocketmq/cluster/broker-b
执行保存: Esc :wq

broker-b-s.properties,第二个Master Broker的Slave节点

[root@dev /soft/rocketmq]# vi ~/rocketmq/cluster/broker-b-s.properties
# ============默认的参数============
brokerClusterName=DefaultCluster
brokerName=broker-b
brokerId=1
deleteWhen=04
fileReservedTime=48
brokerRole=SLAVE
flushDiskType=ASYNC_FLUSH
# ============以下新增============
listenPort=10923
namesrvAddr=127.0.0.1:9876;127.0.0.1:9877
storePathRootDir=/var/rocketmq/broker-b-s/store
storePathCommitLog=/var/rocketmq/broker-b-s/store/commitlog
rocketmqHome=/root/rocketmq/cluster/broker-b-s
执行保存: Esc :wq
  1. 创建rocketmqHome路径,并考入日志配置文件,使每个Broker服务生成不同的日志文件。

broker-a 日志

[root@dev /soft/rocketmq]# mkdir -p ~/rocketmq/cluster/broker-a/conf
[root@dev /soft/rocketmq]# cp ${ROCKETMQ_HOME}/conf/logback_broker.xml ~/rocketmq/cluster/broker-a/conf/
[root@dev /soft/rocketmq]# vi ~/rocketmq/cluster/broker-a/conf/logback_broker.xml
<configuration>
     <property name="user.home" value="/var/rocketmq/broker-a" />
执行保存: Esc :wq

broker-a-s 日志

[root@dev /soft/rocketmq]# mkdir -p ~/rocketmq/cluster/broker-a-s/conf
[root@dev /soft/rocketmq]# cp ${ROCKETMQ_HOME}/conf/logback_broker.xml ~/rocketmq/cluster/broker-a-s/conf/
[root@dev /soft/rocketmq]# vi ~/rocketmq/cluster/broker-a-s/conf/logback_broker.xml
<configuration>
     <property name="user.home" value="/var/rocketmq/broker-a-s" />
执行保存: Esc :wq

broker-b 日志

[root@dev /soft/rocketmq]# mkdir -p ~/rocketmq/cluster/broker-b/conf
[root@dev /soft/rocketmq]# cp ${ROCKETMQ_HOME}/conf/logback_broker.xml ~/rocketmq/cluster/broker-b/conf/
[root@dev /soft/rocketmq]# vi ~/rocketmq/cluster/broker-b/conf/logback_broker.xml
<configuration>
     <property name="user.home" value="/var/rocketmq/broker-b" />
执行保存: Esc :wq

broker-b-s 日志

[root@dev /soft/rocketmq]# mkdir -p ~/rocketmq/cluster/broker-b-s/conf
[root@dev /soft/rocketmq]# cp ${ROCKETMQ_HOME}/conf/logback_broker.xml ~/rocketmq/cluster/broker-b-s/conf/
[root@dev /soft/rocketmq]# vi ~/rocketmq/cluster/broker-b-s/conf/logback_broker.xml
<configuration>
     <property name="user.home" value="/var/rocketmq/broker-b-s" />
执行保存: Esc :wq
  1. 启动
[root@dev /soft/rocketmq]# nohup mqbroker -c ~/rocketmq/cluster/broker-a.properties >/dev/null 2>&1 &
[root@dev /soft/rocketmq]# nohup mqbroker -c ~/rocketmq/cluster/broker-a-s.properties >/dev/null 2>&1 &
[root@dev /soft/rocketmq]# nohup mqbroker -c ~/rocketmq/cluster/broker-b.properties >/dev/null 2>&1 &
[root@dev /soft/rocketmq]# nohup mqbroker -c ~/rocketmq/cluster/broker-b-s.properties >/dev/null 2>&1 &
[root@dev /soft/rocketmq]# tail -f /var/rocketmq/broker-a/logs/rocketmqlogs/broker.log 
[root@dev /soft/rocketmq]# tail -f /var/rocketmq/broker-a-s/logs/rocketmqlogs/broker.log
[root@dev /soft/rocketmq]# tail -f /var/rocketmq/broker-b/logs/rocketmqlogs/broker.log 
[root@dev /soft/rocketmq]# tail -f /var/rocketmq/broker-b-s/logs/rocketmqlogs/broker.log

其它关联指令:

  • 查看Broker主要或者所有参数:mqbroker -m 或者 mqbroker -p

  • 查看集群情况:mqadmin clusterList -n localhost:9876 (使用集群其中一个nameserver即可,多个用分号会报错)

六、服务自启动

  1. NameServer和Broker同时启动的方式
[root@dev /soft/rocketmq]# cd /etc/init.d/
[root@dev /etc/init.d]# vi rocketmq
#!/bin/sh
# chkconfig: 345 85 15
# description: service for rocketmq 4.6.0
# processname: rocketmq

ROCKETMQ_DIR="/soft/rocketmq"

case "$1" in
        start)
                echo "Starting RocketMQ Server"
                # 标准和错误信息不输出
                nohup sh $ROCKETMQ_DIR/bin/mqnamesrv >/dev/null 2>&1 &
                echo "The Name Server boot success..."
                nohup sh $ROCKETMQ_DIR/bin/mqbroker -c $ROCKETMQ_DIR/conf/broker.conf >/dev/null 2>&1 &
                echo "The Broker boot success..."
                echo "RocketMQ started"
                ;;
        stop)
                echo "Stopping RocketMQ Server"
                sh $ROCKETMQ_DIR/bin/mqshutdown broker
                sleep 1 
                sh $ROCKETMQ_DIR/bin/mqshutdown namesrv
                echo "RocketMQ stoped!"
                ;;
        restart)
                echo "Restarting RocketMQ Server"
                $0 stop
                sleep 5
                $0 start
                ;;
        *)
                echo "Usage:$0 {start|stop|restart}"
                exit 1
esac
执行保存: Esc :wq
[root@dev /etc/init.d]# chmod 755 rocketmq
[root@dev /etc/init.d]# chkconfig --add rocketmq
[root@dev /etc/init.d]# chkconfig rocketmq on

其它关联指令:

  • 启动:service rocketmq start
  • 停止:service rocketmq stop
  • 重启:service rocketmq restart
  • 关闭自启动:chkconfig rocketmq off
  • 删除自启动:chkconfig --del rocketmq
  • 显示当前所有java进程:jps
  1. NameServer和Broker单独启动的方式

NameServer

[root@dev /soft/rocketmq]# cd /etc/init.d/
[root@dev /etc/init.d]# vi rocketmq-nameserver-a
#!/bin/sh
# chkconfig: 345 85 15
# description: service for rocketmq 4.6.0
# processname: rocketmq-nameserver-a

ROCKETMQ_DIR="/soft/rocketmq"

case "$1" in
        start)
                echo "Starting RocketMQ NameServer"
                nohup sh $ROCKETMQ_DIR/bin/mqnamesrv -c /root/rocketmq/cluster/nameserver-a.properties >/dev/null 2>&1 &
                echo "RocketMQ NameServer started"
                ;;
        stop)
                echo "Stopping RocketMQ NameServer"
                sh $ROCKETMQ_DIR/bin/mqshutdown namesrv
                echo "RocketMQ NameServer stoped!"
                ;;
        restart)
                echo "Restarting RocketMQ NameServer"
                $0 stop
                sleep 5
                $0 start
                ;;
        *)
                echo "Usage:$0 {start|stop|restart}"
                exit 1
esac
执行保存: Esc :wq
[root@dev /etc/init.d]# chmod 755 rocketmq-nameserver-a
[root@dev /etc/init.d]# chkconfig --add rocketmq-nameserver-a
[root@dev /etc/init.d]# chkconfig rocketmq-nameserver-a on

Broker

[root@dev /soft/rocketmq]# cd /etc/init.d/
[root@dev /etc/init.d]# vi rocketmq-broker-a
#!/bin/sh
# chkconfig: 345 85 15
# description: service for rocketmq 4.6.0
# processname: rocketmq-broker-a

ROCKETMQ_DIR="/soft/rocketmq"

case "$1" in
        start)
                echo "Starting RocketMQ Broker"
                nohup sh $ROCKETMQ_DIR/bin/mqbroker -c /root/rocketmq/cluster/broker-a.properties >/dev/null 2>&1 &
                echo "RocketMQ Broker started"
                ;;
        stop)
                echo "Stopping RocketMQ Broker"
                sh $ROCKETMQ_DIR/bin/mqshutdown broker
                echo "RocketMQ Broker stoped!"
                ;;
        restart)
                echo "Restarting RocketMQ Broker"
                $0 stop
                sleep 5
                $0 start
                ;;
        *)
                echo "Usage:$0 {start|stop|restart}"
                exit 1
esac
执行保存: Esc :wq
[root@dev /etc/init.d]# chmod 755 rocketmq-broker-a
[root@dev /etc/init.d]# chkconfig --add rocketmq-broker-a
[root@dev /etc/init.d]# chkconfig rocketmq-broker-a on

如果同台安装多个节点的情况,停止的脚本会停掉全部同类节点。如果想单独关闭,需要在官方脚本的基础上,扩展些我们自定义的关闭脚本。(题外话,看脚本能猜出官方不建议在一台机器部署多个节点)

这里主要是把脚本中原grep java,替换为grep $2.properties

[root@dev /soft/rocketmq/bin]# cp mqshutdown mqshutdownsingle
[root@dev /soft/rocketmq/bin]# vi mqshutdownsingle
#!/bin/sh

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

case $1 in
    broker)

    pid=`ps ax | grep -i 'org.apache.rocketmq.broker.BrokerStartup' |grep $2.properties | grep -v grep | awk '{print $1}'`
    if [ -z "$pid" ] ; then
            echo "No mqbroker running."
            exit -1;
    fi

    echo "The mqbroker(${pid}) is running..."

    kill ${pid}

    echo "Send shutdown request to mqbroker(${pid}) OK"
    ;;
    namesrv)

    pid=`ps ax | grep -i 'org.apache.rocketmq.namesrv.NamesrvStartup' |grep $2.properties | grep -v grep | awk '{print $1}'`
    if [ -z "$pid" ] ; then
            echo "No mqnamesrv running."
            exit -1;
    fi

    echo "The mqnamesrv(${pid}) is running..."

    kill ${pid}

    echo "Send shutdown request to mqnamesrv(${pid}) OK"
    ;;
    *)
    echo "Useage: mqshutdown broker | namesrv"
esac
执行保存: Esc :wq

停止脚本增加了一个指定节点名称的参数

[root@dev /soft/rocketmq]# mqshutdownsingle namesrv nameserver-a
[root@dev /soft/rocketmq]# mqshutdownsingle broker broker-a

七、扩展内容

1. Broker配置参数简单整理(还是读源码来的直接)

消息存储参数(MessageStoreConfig源码类名) 键名 键值/描述
maxMessageSize 最大的消息大小,默认1024*1024*4 (4M),单位字节B
mappedFileSizeCommitLog CommitLog每个文件大小,默认1024*1024*10241(1G),单位字节B
mappedFileSizeConsumeQueue ConsumeQueue每个文件默认存储条数,默认300000*20(30W),20为存储的单位大小
flushIntervalConsumeQueue ConsumeQueue刷盘间隔,默认1000,单位毫秒

2. 消息不丢失的思考

不丢失消息,同时也兼顾性能的话,我思考的结论是这样:

  1. master必须选择同步刷盘(flushDiskType=SYNC_FLUSH),保证消息一定要落在硬盘上。

  2. master同步slave数据的方式可以选择异步复制(brokerRole=ASYNC_MASTER),但master至少要对应1个以上的slave(3台以上最好),以保证至少有一台slave能成功备份。

  3. slave的刷盘模式可以考虑用异步刷盘,毕竟它主要用于备份,而且存在多个兄弟slave。用同步的话,感觉有些浪费性能。

    但理论归理论,这里完全凭经验想象。如想通透的话,还需多看源码、多实战,方可升级打怪。

3.mqadmin指令

  1. 查询指令的用法
  • 查看所有指令

    [root@dev ~]# mqadmin
    The most commonly used mqadmin commands are:
       updateTopic          Update or create topic
       deleteTopic          Delete topic from broker and NameServer.
       updateSubGroup       Update or create subscription group
       deleteSubGroup       Delete subscription group from broker.
       updateBrokerConfig   Update broker's config
       ......
    
  • 查看每条指令的使用方法,以updateTopic举例(用到的参数,应该很好明白)

    [root@dev ~]# mqadmin help updateTopic
    usage: mqadmin updateTopic -b <arg> | -c <arg>  [-h] [-n <arg>] [-o <arg>] [-p <arg>] [-r <arg>] [-s <arg>] -t
           <arg> [-u <arg>] [-w <arg>]
     -b,--brokerAddr <arg>       create topic to which broker
     -c,--clusterName <arg>      create topic to which cluster
     -h,--help                   Print help
     -n,--namesrvAddr <arg>      Name server address list, eg: 192.168.0.1:9876;192.168.0.2:9876
     -o,--order <arg>            set topic's order(true|false)
     -p,--perm <arg>             set topic's permission(2|4|6), intro[2:W 4:R; 6:RW]
     -r,--readQueueNums <arg>    set read queue nums
     -s,--hasUnitSub <arg>       has unit sub (true|false)
     -t,--topic <arg>            topic name
     -u,--unit <arg>             is unit topic (true|false)
     -w,--writeQueueNums <arg>   set write queue nums
    
  1. 常用指令备忘录
# 创建消息主题。主要就是CNT,BNT。。。
# 为什么用命令创建?还是建议禁止开启自动创建主题的功能,以防项目中开发随意创建主题,导致最终维护困难。
# 通过指定集群的方式
[root@dev ~]# mqadmin updateTopic -c DefaultCluster -n localhost:9876 -t xx-topic
# 通过指定broker的方式
[root@dev ~]# mqadmin updateTopic -b localhost:10911 -n localhost:9876 -t xx-topic
# 删除主题
[root@dev ~]# mqadmin deleteTopic -c DefaultCluster -n localhost:9876 -t xx-topic
# 查看主题
[root@dev ~]# mqadmin topicRoute -n localhost:9876 -t xx-topic

附录: