Linux 生产环境搭建 RocketMQ 集群

大纲

前言

本文将使用两台物理主机来搭建 RocketMQ 集群,包括双节点 NameServer 集群、双主双从(2M-2S)异步复制的 Broker 集群和 RocketMQ 控制台,适用于 CentOS / Debian / Ubuntu 等 Linux 发行版。

集群部署理论介绍

RocketMQ 集群部署实战

本节将为 RocketMQ 搭建双节点 NameServer 集群和双主双从(2M-2S)异步复制的 Broker 集群。

版本说明

组件版本说明
RocketMQ Server4.9.0RocketMQ 服务端(包括 NameServer 和 Broker),运行时依赖 JDK 1.8+,NameServer 默认监听 9876 端口,Broker 默认监听 10911 端口
RocketMQ Console1.0.0RocketMQ 控制台,编译源码时依赖 JDK 1.7,运行时依赖 JDK 1.7+,默认监听 8080 端口

整体架构

NameServer 集群说明

NameServer 集群是无状态的,去中心化的,即 NameServer 集群中的各个节点间是没有地位差异,各节点之间相互不进行信息通讯。那各节点中的数据是如何进行数据同步的呢?在 Broker 节点启动时,会轮询 NameServer 列表,与 NameServer 集群中的所有节点建立长连接,并定时向所有 NameServer 节点注册 Topic 路由信息,以保证路由信息的一致性与可用性。在每个 NameServer 的内部维护着⼀个完整的 Broker 列表,用来动态存储 Broker 的信息。

Broker 集群说明

Broker 集群本质上是一个主从集群,集群节点分为 Master 节点 与 Slave 节点两种角色,其中 Master 节点负责处理读写操作请求,Slave 节点负责对 Master 节点中的数据进行同步备份。当 Master 节点宕机后,在具备自动切换能力(例如 DLedger 模式或者 Controller 模式)的情况下,Slave 节点可以被提升为 Master 节点继续对外提供服务,因此整体上可以看作主备架构。特别注意,在 RocketMQ 4.5 版本之前,传统的主从架构并不支持自动主从切换;RocketMQ 从 4.5 版本开始引入 DLedger 模式后,才开始支持自动主从切换;5.x 版本又引入了 Controller 模式,但只有手动开启 Controller 才支持自动切换,否则仍然不具备自动主从切换能力。

搭建规划

为了演示方便,这里仅使用两台物理主机来搭建双节点 NameServer 集群和双主双从(2M-2S)异步复制的 Broker 集群,两台物理主机的功能与 Broker 角色分配如下表所示:

物理主机序号主机名 IP 功能 Broker 角色 Broker 刷盘策略 Broker 复制策略
1rocketmq1192.168.2.234NameServer + BrokerMaster Broker 1 + Slave Broker 2 异步刷盘异步复制
2rocketmq2192.168.2.148NameServer + BrokerMaster Broker 2 + Slave Broker 1 异步刷盘异步复制

RocketMQ 集群搭建建议

  • 在条件允许的情况下,生产环境中可以使用多台物理主机搭建 NamerServer 集群和 Broker 集群,即 NamerServer 集群采用三节点架构,Broker 集群采用三主三从(3M-3S)的异步复制架构。该方案能够提供更高的吞吐能力、更好的容灾能力,并使 Topic / Queue 分布更加均衡,适用于高并发场景(如交易系统、日志平台)。
  • 比如,生产环境中可采用 9 台物理机器进行完全隔离部署:其中 3 台服务器分别独立部署 3 个 NameServer 节点,构成 NameServer 集群;另外 6 台用于部署 Broker 集群,按主从架构部署为三主三从(3M-3S),其中 3 台分别部署 Master Broker,另外 3 台分别部署对应的 Slave Broker,实现高可用与数据冗余。
  • 在生产环境中,即使 Broker 集群已采用主从架构,如果 Master 与 Slave 之间是采用异步复制策略,仍然存在数据尚未同步即发生故障而导致数据丢失的风险。同时,为了避免单个磁盘损坏造成数据丢失,并提升磁盘写入性能,所有 Master 节点都必须配置 RAID10 磁盘阵列作为基础保障。特别注意,异步刷盘解决的是写入性能问题,RAID10 磁盘阵列解决的是磁盘可靠性问题,两者都无法避免 "刷盘前" 这段时间窗口的数据丢失,除非是使用同步刷盘。

配置集群

多物理主机操作

在所有物理主机上(包括 rocketmq1rocketmq2),分别执行以下所有操作,为 RocketMQ 集群的搭建做准备。

创建用户

特别注意

本文所有命令默认都是在 rocketmq 用户权限下执行,除了特别说明除外(比如 sudo xxxx 命令)。

  • 创建用户组
1
sudo groupadd rocketmq
  • 创建用户(禁止登录)
1
sudo useradd -g rocketmq -m -s /sbin/nologin rocketmq
  • 切换用户
1
sudo -u rocketmq -s
系统配置

设置主机名

  • 设置主机名,比如 rocketmq1 或者 rocketmq2
1
sudo hostnamectl set-hostname xxxxx

防火墙配置

  • CentOS、Fedora 关闭防火墙
1
2
3
4
5
6
7
8
# 立即关闭防火墙
sudo systemctl stop firewalld

# 关闭开机自启
sudo systemctl disable firewalld

# 查看防火墙状态
sudo systemctl status firewalld
  • Debian、Ubuntu 关闭防火墙
1
2
3
4
5
6
7
8
# 立即关闭防火墙
sudo ufw disable

# 关闭开机自启
sudo systemctl disable ufw

# 查看防火墙状态
sudo ufw status
环境准备

版本说明

RocketMQ 的服务端(4.9.0 版本)包含两个服务,分别是 NameServer 和 Broker 服务,这两个服务都需要单独启动,且运行时都依赖 JDK 1.8+

JDK 手动安装

  • 下载并安装 JDK(1.8 版本)
1
2
3
4
5
6
7
8
# 下载文件(OpenJDK 1.8,Azul Zulu 发行版)
wget https://cdn.azul.com/zulu/bin/zulu8.76.0.17-ca-jdk8.0.402-linux_x64.tar.gz

# 解压文件
tar -zxvf zulu8.76.0.17-ca-jdk8.0.402-linux_x64.tar.gz

# 移动文件
sudo mv zulu8.76.0.17-ca-jdk8.0.402-linux_x64 /usr/local/jdk-1.8.0_402

全局环境变量配置

  • 配置系统环境变量
1
2
# 编辑系统配置文件,在文件末尾添加以下内容
sudo vi /etc/profile
1
2
export JAVA_HOME=/usr/local/jdk-1.8.0_402
export PATH=$JAVA_HOME/bin:$PATH
  • 让系统环境变量生效
1
sudo source /etc/profile

用户环境变量配置

1
2
# 切换至 rocketmq 用户
sudo -u rocketmq -s
1
2
# 编辑用户配置文件,在文件末尾添加以下内容
vi ~/.bashrc
1
2
export JAVA_HOME=/usr/local/jdk-1.8.0_402
export PATH=$JAVA_HOME/bin:$PATH
  • 让用户环境变量生效
1
source ~/.bashrc

验证 JDK 安装

1
java -version
软件下载

RocketMQ 官网 下载对应版本的二进制压缩包(比如 rocketmq-all-4.9.0-bin-release.zip),如下图所示:

  • 安装工具
1
2
3
4
5
# CentOS、Fedora
sudo yum install -y wget unzip

# Debian、Ubuntu
sudo apt install -y wget unzip
  • 下载文件
1
wget https://archive.apache.org/dist/rocketmq/4.9.0/rocketmq-all-4.9.0-bin-release.zip
  • 解压文件
1
2
3
4
5
6
7
8
# 解压文件
unzip rocketmq-all-4.9.0-bin-release.zip

# 解压目录重命名
mv rocketmq-all-4.9.0-bin-release rocketmq-all-4.9.0

# 进入解压目录
cd rocketmq-all-4.9.0
JVM 配置

更改 NameServer 的 JVM 配置参数

  • 编辑 runserver.sh 脚本文件,根据物理主机的实际内存大小修改 NameServer 的 JVM 配置参数
1
2
# 编辑 NameServer 的启动脚本文件,更改以下内容
vi bin/runserver.sh
1
JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"

更改 Broker 的 JVM 配置参数

  • 编辑 runbroker.sh 脚本文件,根据物理主机的实际内存大小修改 Broker 的 JVM 配置参数
1
2
# 编辑 Broker 的启动脚本文件,更改以下内容
vi bin/runbroker.sh
1
JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g"

物理主机一操作

在物理主机一上(rocketmq1),分别执行以下所有操作,目的是部署 Master Broker 1 和 Slave Broker 2。

创建存储目录
  • 创建 Master Broker 1 的数据存储目录
1
2
3
mkdir -p /home/rocketmq/store-m1/index
mkdir -p /home/rocketmq/store-m1/commitlog
mkdir -p /home/rocketmq/store-m1/consumequeue
  • 创建 Slave Broker 2 的数据存储目录
1
2
3
mkdir -p /home/rocketmq/store-s2/index
mkdir -p /home/rocketmq/store-s2/commitlog
mkdir -p /home/rocketmq/store-s2/consumequeue
配置 Broker

特别注意

在更改 Broker 的配置文件时,如果遇到路径相关的配置(如 storePathRootDirstorePathCommitLog 等),则必须使用绝对路径,不能使用相对路径,比如 storePathRootDir=~/store,否则 Broker 可能会启动失败。

  • 进入 RocketMQ 的配置目录(双主双从异步复制)
1
cd rocketmq-all-4.9.0/conf/2m-2s-async/
  • 更改配置文件 broker-a.properties 的内容(如下),作为 Master Broker 1 的核心配置文件
1
2
# 编辑配置文件,添加以下配置内容
vi broker-a.properties
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 指定整个 Broker 集群的名称,或者说是 RocketMQ 集群的名称
brokerClusterName=DefaultCluster
# 指定 Master-Slave 集群的名称,一个 RocketMQ 集群可以包含多个 Master-Slave 集群
brokerName=broker-a
# Master 的 brokerId 为 0
brokerId=0
# 指定删除消息存储过期文件的时间为凌晨 4 点
deleteWhen=04
# 指定未发生更新的消息存储文件的保留时长为 48 小时,48 小时后过期,将会被删除
fileReservedTime=48
# 指定当前 Broker 为异步复制 Master
brokerRole=ASYNC_MASTER
# 指定刷盘策略为异步刷盘
flushDiskType=ASYNC_FLUSH
# 指定 NameServer 地址列表,分号分割
namesrvAddr=192.168.2.234:9876;192.168.2.148:9876
# 指定消息存储相关的根目录路径,默认是当前用户主目录
storePathRootDir=/home/rocketmq/store-m1
# 指定 CommitLog 目录路径
storePathCommitLog=/home/rocketmq/store-m1/commitlog
# 指定 ConsumeQueue 目录路径
storePathConsumeQueue=/home/rocketmq/store-m1/consumequeue
# 指定 Index 目录路径
storePathIndex=/home/rocketmq/store-m1/index
# 指定 Checkpoint 文件路径
storeCheckpoint=/home/rocketmq/store-m1/checkpoint
# 指定 Abort 文件路径
abortFile=/home/rocketmq/store-m1/abort
  • 更改配置文件 broker-b-s.properties 的内容(如下),作为 Slave Broker 2 的核心配置文件
1
2
# 编辑配置文件,添加以下配置内容
vi broker-b-s.properties
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Broker集群名称
brokerClusterName=DefaultCluster
# 指定另外一个 Master-Slave 集群的名称,一个 RocketMQ 集群可以包含多个 Master-Slave 集群
brokerName=broker-b
# Slave 的 brokerId 为非 0
brokerId=1
# 指定删除消息存储过期文件的时间为凌晨 4 点
deleteWhen=04
# 指定未发生更新的消息存储文件的保留时长为 48 小时,48 小时后过期,将会被删除
fileReservedTime=48
# 指定当前 Broker 为 Slave
brokerRole=SLAVE
# 指定刷盘策略为异步刷盘
flushDiskType=ASYNC_FLUSH
# 指定 NameServer 地址列表,分号分割
namesrvAddr=192.168.2.234:9876;192.168.2.148:9876
# 指定 Broker 对外提供服务的端口,由于当前主机同时部署 Master 1 与 Slave 2,需要将端口与 Master 1 的默认端口区分开
listenPort=11911
# 指定消息存储相关的根目录路径,默认是当前用户主目录,需要与 Master 1 的默认根目录路径区分开
storePathRootDir=/home/rocketmq/store-s2
# 指定 CommitLog 目录路径
storePathCommitLog=/home/rocketmq/store-s2/commitlog
# 指定 ConsumeQueue 目录路径
storePathConsumeQueue=/home/rocketmq/store-s2/consumequeue
# 指定 Index 目录路径
storePathIndex=/home/rocketmq/store-s2/index
# 指定 Checkpoint 文件路径
storeCheckpoint=/home/rocketmq/store-s2/checkpoint
# 指定 Abort 文件路径
abortFile=/home/rocketmq/store-s2/abort
  • 除了以上核心配置外,这些配置文件中还可以按需配置其它属性(如果不配置,则会使用对应的默认值),完整的配置示例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# 指定整个 Broker 集群的名称,或者说是 RocketMQ 集群的名称
brokerClusterName=RocketMQCluster
# 指定 Master-Slave 集群的名称,一个 RocketMQ 集群可以包含多个 Master-Slave 集群
brokerName=broker-a
# 0 表示 Master,大于 0 表示 Slave
brokerId=0
# NameServer 地址列表,分号分割
namesrvAddr=nameserver1:9876;nameserver2:9876
# 默认新建 Topic 所创建的队列数
defaultTopicQueueNums=4
# 是否允许 Broker 自动创建 Topic,建议生产环境中关闭
autoCreateTopicEnable=true
# 是否允许 Broker 自动创建订阅组,建议生产环境中关闭
autoCreateSubscriptionGroup=true
# Broker 对外提供服务的端口,即 Broker 与 Producer、Consumer 通信的端口
listenPort=10911
# HA 高可用监听端口,即 Master 与 Slave 间通信的端口,默认值为 listenPort + 1
haListenPort=10912
# 指定删除消息存储过期文件的时间为凌晨 4 点
deleteWhen=04
# 指定未发生更新的消息存储文件的保留时长为 48 小时,48 小时后过期,将会被删除
fileReservedTime=48
# 指定 CommitLog 目录中每个文件的大小,默认 1G
mapedFileSizeCommitLog=1073741824
# 指定 ConsumeQueue 的每个 Topic 的每个 Queue 文件中可以存放的消息数量,默认 30 万条
mapedFileSizeConsumeQueue=300000
# 在清除过期文件时,如果该文件被其他线程占用(引用数大于 0,比如读取消息),此时会阻止此次删除任务,同时在第一次试图删除该文件时记录当前时间戳。该属性则表示从第一次拒绝删除后开始计时,该文件最多可以保留的时长。在此时间内若引用数仍不为 0,则删除仍会被拒绝。不过时间到后,文件将被强制删除
destroyMapedFileIntervalForcibly=120000
# 指定 CommitLog、ConsumeQueue 所在磁盘分区的最大存储空间使用率,超过该值,则需立即清除过期文件
diskMaxUsedSpaceRatio=88
# 指定消息存储相关的根目录路径,默认是当前用户主目录
storePathRootDir=/home/rocketmq/store
# 指定 CommitLog 目录路径
storePathCommitLog=/home/rocketmq/store/commitlog
# 指定 ConsumeQueue 目录路径
storePathConsumeQueue=/home/rocketmq/store/consumequeue
# 指定 Index 目录路径
storePathIndex=/home/rocketmq/store/index
# 指定 Checkpoint 文件路径
storeCheckpoint=/home/rocketmq/store/checkpoint
# 指定 Abort 文件路径
abortFile=/home/rocketmq/store/abort
# 指定消息的最大大小
maxMessagesize=65536
# 指定 Broker 的角色,可选值:ASYNC_MASTER(异步复制 Master)、SYNC_MASTER(同步复制 Master)、SLAVE
brokerRole=SYNC_MASTER
# 指定刷盘策略,可选值:ASYNC_FLUSH(异步刷盘)、SYNC_FLUSH(同步刷盘)
flushDiskType=SYNC_FLUSH
# 指定发送消息线程池数量
sendMessageThreadPoolNums=128
# 指定拉取消息线程池数量
pullMessageThreadPoolNums=128
# 强制指定本机 IP,需要根据每台机器进行修改。官方介绍可为空,系统默认自动识别,但多网卡时 IP 地址可能读取错误
brokerIP1=192.168.2.234

物理主机二操作

在物理主机二上(rocketmq2),分别执行以下所有操作,目的是部署 Master Broker 2 和 Slave Broker 1。

创建存储目录
  • 创建 Master Broker 2 的数据存储目录
1
2
3
mkdir -p /home/rocketmq/store-m2/index
mkdir -p /home/rocketmq/store-m2/commitlog
mkdir -p /home/rocketmq/store-m2/consumequeue
  • 创建 Slave Broker 1 的数据存储目录
1
2
3
mkdir -p /home/rocketmq/store-s1/index
mkdir -p /home/rocketmq/store-s1/commitlog
mkdir -p /home/rocketmq/store-s1/consumequeue
配置 Broker

特别注意

在更改 Broker 的配置文件时,如果遇到路径相关的配置(如 storePathRootDirstorePathCommitLog 等),则必须使用绝对路径,不能使用相对路径,比如 storePathRootDir=~/store,否则 Broker 可能会启动失败。

  • 进入 RocketMQ 的配置目录(双主双从异步复制)
1
cd rocketmq-all-4.9.0/conf/2m-2s-async/
  • 更改配置文件 broker-b.properties 的内容(如下),作为 Master Broker 2 的核心配置文件
1
2
# 编辑配置文件,添加以下配置内容
vi broker-b.properties
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 指定整个 Broker 集群的名称,或者说是 RocketMQ 集群的名称
brokerClusterName=DefaultCluster
# 指定 Master-Slave 集群的名称,一个 RocketMQ 集群可以包含多个 Master-Slave 集群
brokerName=broker-b
# Master 的 brokerId 为 0
brokerId=0
# 指定删除消息存储过期文件的时间为凌晨 4 点
deleteWhen=04
# 指定未发生更新的消息存储文件的保留时长为 48 小时,48 小时后过期,将会被删除
fileReservedTime=48
# 指定当前 Broker 为异步复制 Master
brokerRole=ASYNC_MASTER
# 指定刷盘策略为异步刷盘
flushDiskType=ASYNC_FLUSH
# 指定 NameServer 地址列表,分号分割
namesrvAddr=192.168.2.234:9876;192.168.2.148:9876
# 指定消息存储相关的根目录路径,默认是当前用户主目录
storePathRootDir=/home/rocketmq/store-m2
# 指定 CommitLog 目录路径
storePathCommitLog=/home/rocketmq/store-m2/commitlog
# 指定 ConsumeQueue 目录路径
storePathConsumeQueue=/home/rocketmq/store-m2/consumequeue
# 指定 Index 目录路径
storePathIndex=/home/rocketmq/store-m2/index
# 指定 Checkpoint 文件路径
storeCheckpoint=/home/rocketmq/store-m2/checkpoint
# 指定 Abort 文件路径
abortFile=/home/rocketmq/store-m2/abort
  • 更改配置文件 broker-a-s.properties 的内容(如下),作为 Slave Broker 1 的核心配置文件
1
2
# 编辑配置文件,添加以下配置内容
vi broker-a-s.properties
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Broker集群名称
brokerClusterName=DefaultCluster
# 指定另外一个 Master-Slave 集群的名称,一个 RocketMQ 集群可以包含多个 Master-Slave 集群
brokerName=broker-a
# Slave 的 brokerId 为非 0
brokerId=1
# 指定删除消息存储过期文件的时间为凌晨 4 点
deleteWhen=04
# 指定未发生更新的消息存储文件的保留时长为 48 小时,48 小时后过期,将会被删除
fileReservedTime=48
# 指定当前 Broker 为 Slave
brokerRole=SLAVE
# 指定刷盘策略为异步刷盘
flushDiskType=ASYNC_FLUSH
# 指定 NameServer 地址列表,分号分割
namesrvAddr=192.168.2.234:9876;192.168.2.148:9876
# 指定 Broker 对外提供服务的端口,由于当前主机同时部署 Master 2 与 Slave 1,需要将端口与 Master 2 的默认端口区分开
listenPort=11911
# 指定消息存储相关的根目录路径,默认是当前用户主目录,需要与 Master 2 的默认根目录路径区分开
storePathRootDir=/home/rocketmq/store-s1
# 指定 CommitLog 目录路径
storePathCommitLog=/home/rocketmq/store-s1/commitlog
# 指定 ConsumeQueue 目录路径
storePathConsumeQueue=/home/rocketmq/store-s1/consumequeue
# 指定 Index 目录路径
storePathIndex=/home/rocketmq/store-s1/index
# 指定 Checkpoint 文件路径
storeCheckpoint=/home/rocketmq/store-s1/checkpoint
# 指定 Abort 文件路径
abortFile=/home/rocketmq/store-s1/abort
  • 除了以上核心配置外,这些配置文件中还可以按需配置其它属性(如果不配置,则会使用对应的默认值),完整的配置示例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# 指定整个 Broker 集群的名称,或者说是 RocketMQ 集群的名称
brokerClusterName=RocketMQCluster
# 指定 Master-Slave 集群的名称,一个 RocketMQ 集群可以包含多个 Master-Slave 集群
brokerName=broker-a
# 0 表示 Master,大于 0 表示 Slave
brokerId=0
# NameServer 地址列表,分号分割
namesrvAddr=nameserver1:9876;nameserver2:9876
# 默认新建 Topic 所创建的队列数
defaultTopicQueueNums=4
# 是否允许 Broker 自动创建 Topic,建议生产环境中关闭
autoCreateTopicEnable=true
# 是否允许 Broker 自动创建订阅组,建议生产环境中关闭
autoCreateSubscriptionGroup=true
# Broker 对外提供服务的端口,即 Broker 与 Producer、Consumer 通信的端口
listenPort=10911
# HA 高可用监听端口,即 Master 与 Slave 间通信的端口,默认值为 listenPort + 1
haListenPort=10912
# 指定删除消息存储过期文件的时间为凌晨 4 点
deleteWhen=04
# 指定未发生更新的消息存储文件的保留时长为 48 小时,48 小时后过期,将会被删除
fileReservedTime=48
# 指定 CommitLog 目录中每个文件的大小,默认 1G
mapedFileSizeCommitLog=1073741824
# 指定 ConsumeQueue 的每个 Topic 的每个 Queue 文件中可以存放的消息数量,默认 30 万条
mapedFileSizeConsumeQueue=300000
# 在清除过期文件时,如果该文件被其他线程占用(引用数大于 0,比如读取消息),此时会阻止此次删除任务,同时在第一次试图删除该文件时记录当前时间戳。该属性则表示从第一次拒绝删除后开始计时,该文件最多可以保留的时长。在此时间内若引用数仍不为 0,则删除仍会被拒绝。不过时间到后,文件将被强制删除
destroyMapedFileIntervalForcibly=120000
# 指定 CommitLog、ConsumeQueue 所在磁盘分区的最大存储空间使用率,超过该值,则需立即清除过期文件
diskMaxUsedSpaceRatio=88
# 指定消息存储相关的根目录路径,默认是当前用户主目录
storePathRootDir=/home/rocketmq/store
# 指定 CommitLog 目录路径
storePathCommitLog=/home/rocketmq/store/commitlog
# 指定 ConsumeQueue 目录路径
storePathConsumeQueue=/home/rocketmq/store/consumequeue
# 指定 Index 目录路径
storePathIndex=/home/rocketmq/store/index
# 指定 Checkpoint 文件路径
storeCheckpoint=/home/rocketmq/store/checkpoint
# 指定 Abort 文件路径
abortFile=/home/rocketmq/store/abort
# 指定消息的最大大小
maxMessagesize=65536
# 指定 Broker 的角色,可选值:ASYNC_MASTER(异步复制 Master)、SYNC_MASTER(同步复制 Master)、SLAVE
brokerRole=SYNC_MASTER
# 指定刷盘策略,可选值:ASYNC_FLUSH(异步刷盘)、SYNC_FLUSH(同步刷盘)
flushDiskType=SYNC_FLUSH
# 指定发送消息线程池数量
sendMessageThreadPoolNums=128
# 指定拉取消息线程池数量
pullMessageThreadPoolNums=128
# 强制指定本机 IP,需要根据每台机器进行修改。官方介绍可为空,系统默认自动识别,但多网卡时 IP 地址可能读取错误
brokerIP1=192.168.2.234

启动集群

特别注意

  • 在生产环境中,为了系统安全,强烈建议使用普通用户(比如 rocketmq)权限来启动 RocketMQ 的 NameServer 和 Broker 服务
  • 在生产环境中,强烈建议使用 Systemd 或 Supervisor 等进程管理工具来管理 RocketMQ 的 NameServer 和 Broker 服务,以实现进程守护和故障自动重启。

NameServer 集群

由于 NameServer 集群无主从关系、去中心化设计,因此所有 NameServer 节点的启动命令都是相同的。

启动第一个节点
  • 在物理主机一上(rocketmq1),启动 NameServer 集群的第一个节点
1
2
3
4
5
6
7
8
9
10
11
# 进入 RocketMQ 的安装目录
cd rocketmq-all-4.9.0

# 后台启动 NameServer
nohup sh bin/mqnamesrv &

# 查看 NameServer 的进程信息
ps -aux|grep namesrv

# 查看 NameServer 的日志信息
tail -f ~/logs/rocketmqlogs/namesrv.log
启动第二个节点
  • 在物理主机二上(rocketmq2),启动 NameServer 集群的第二个节点
1
2
3
4
5
6
7
8
9
10
11
# 进入 RocketMQ 的安装目录
cd rocketmq-all-4.9.0

# 后台启动 NameServer
nohup sh bin/mqnamesrv &

# 查看 NameServer 的进程信息
ps -aux|grep namesrv

# 查看 NameServer 的日志信息
tail -f ~/logs/rocketmqlogs/namesrv.log

Broker 集群

由于 Broker 集群存在主从关系,因此不同 Master 和 Slave 节点启动时所要加载的配置文件是不同的。值得一提的是,不同 Broker 节点对应的配置文件如下表所示:

物理主机序号 Broker 角色配置文件
1Master Broker 1rocketmq-all-4.9.0/conf/2m-2s-async/broker-a.properties
1Slave Broker 2rocketmq-all-4.9.0/conf/2m-2s-async/broker-b-s.properties
2Master Broker 2rocketmq-all-4.9.0/conf/2m-2s-async/broker-b.properties
2Slave Broker 1rocketmq-all-4.9.0/conf/2m-2s-async/broker-a-s.properties

Broker 启动失败原因排查

  • 如果 Broker 无法正常启动,可以查看以下日志文件来排查问题:
  • ~/logs/rocketmqlogs/store.log
  • ~/logs/rocketmqlogs/broker.log
启动两个 Master
  • 在物理主机一上(rocketmq1),启动 Master Broker 1
1
2
3
4
5
6
7
8
9
10
11
# 进入 RocketMQ 的安装目录
cd rocketmq-all-4.9.0

# 启动 Master Broker 1
nohup sh bin/mqbroker -c conf/2m-2s-async/broker-a.properties &

# 查看 Master Broker 1 的进程信息
ps -aux|grep broker

# 查看 Master Broker 1 的日志信息
tail -f ~/logs/rocketmqlogs/broker.log
  • 在物理主机二上(rocketmq2),启动 Master Broker 2
1
2
3
4
5
6
7
8
9
10
11
# 进入 RocketMQ 的安装目录
cd rocketmq-all-4.9.0

# 启动 Master Broker 2
nohup sh bin/mqbroker -c conf/2m-2s-async/broker-b.properties &

# 查看 Master Broker 2 的进程信息
ps -aux|grep broker

# 查看 Master Broker 2 的日志信息
tail -f ~/logs/rocketmqlogs/broker.log
启动两个 Slave
  • 在物理主机一上(rocketmq1),启动 Slave Broker 2
1
2
3
4
5
6
7
8
9
10
11
# 进入 RocketMQ 的安装目录
cd rocketmq-all-4.9.0

# 启动 Slave Broker 2
nohup sh bin/mqbroker -c conf/2m-2s-async/broker-b-s.properties &

# 查看 Slave Broker 2 的进程信息
ps -aux|grep broker

# 查看 Slave Broker 2 的日志信息
tail -f ~/logs/rocketmqlogs/broker.log
  • 在物理主机二上(rocketmq2),启动 Slave Broker 1
1
2
3
4
5
6
7
8
9
10
11
# 进入 RocketMQ 的安装目录
cd rocketmq-all-4.9.0

# 启动 Slave Broker 1
nohup sh bin/mqbroker -c conf/2m-2s-async/broker-a-s.properties &

# 查看 Slave Broker 1 的进程信息
ps -aux|grep broker

# 查看 Slave Broker 1 的日志信息
tail -f ~/logs/rocketmqlogs/broker.log

测试集群

发送消息

1
2
3
4
5
# 进入 RocketMQ 的安装目录
cd rocketmq-all-4.9.0

# 启动消息生产者(测试专用),其中 NAMESRV_ADDR 是 NameServer 的地址列表(分号隔开),输出内容如下
export NAMESRV_ADDR="192.168.2.234:9876;192.168.2.148:9876" && sh bin/tools.sh org.apache.rocketmq.example.quickstart.Producer
1
2
3
SendResult [sendStatus=SEND_OK, msgId=FD34DD838CB90000AC480E823DAC73A022B028D93B30378408E803E5, offsetMsgId=C0A802EA00002A9F0000000000037483, messageQueue=MessageQueue [topic=TopicTest, brokerName=broker-a, queueId=2], queueOffset=249]
SendResult [sendStatus=SEND_OK, msgId=FD34DD838CB90000AC480E823DAC73A022B028D93B30378408EB03E6, offsetMsgId=C0A802EA00002A9F0000000000037566, messageQueue=MessageQueue [topic=TopicTest, brokerName=broker-a, queueId=3], queueOffset=249]
SendResult [sendStatus=SEND_OK, msgId=FD34DD838CB90000AC480E823DAC73A022B028D93B30378408EF03E7, offsetMsgId=C0A8029400002A9F0000000000037568, messageQueue=MessageQueue [topic=TopicTest, brokerName=broker-b, queueId=0], queueOffset=249]

接收消息

1
2
3
4
5
# 进入 RocketMQ 的安装目录
cd rocketmq-all-4.9.0

# 启动消息消费者(测试专用),其中 NAMESRV_ADDR 是 NameServer 的地址列表(分号隔开),输出内容如下
export NAMESRV_ADDR="192.168.2.234:9876;192.168.2.148:9876" && sh bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer
1
2
3
ConsumeMessageThread_9 Receive New Messages: [MessageExt [brokerName=broker-b, queueId=3, storeSize=227, queueOffset=178, sysFlag=0, bornTimestamp=1775904198499, bornHost=/192.168.2.148:33524, storeTimestamp=1775904198500, storeHost=/192.168.2.148:10911, msgId=C0A8029400002A9F00000000000278B1, commitLogOffset=161969, bodyCRC=1570433042, reconsumeTimes=0, preparedTransactionOffset=0, toString()=Message{topic='TopicTest', flag=0, properties={MIN_OFFSET=0, MAX_OFFSET=250, CONSUME_START_TIME=1775904266402, UNIQ_KEY=FD34DD838CB90000AC480E823DAC73A022B028D93B303784036301AA, CLUSTER=DefaultCluster, WAIT=true, TAGS=TagA}, body=[72, 101, 108, 108, 111, 32, 82, 111, 99, 107, 101, 116, 77, 81, 32, 52, 50, 54], transactionId='null'}]] 
ConsumeMessageThread_12 Receive New Messages: [MessageExt [brokerName=broker-b, queueId=3, storeSize=227, queueOffset=171, sysFlag=0, bornTimestamp=1775904198336, bornHost=/192.168.2.148:33524, storeTimestamp=1775904198336, storeHost=/192.168.2.148:10911, msgId=C0A8029400002A9F0000000000025FDD, commitLogOffset=155613, bodyCRC=1287761895, reconsumeTimes=0, preparedTransactionOffset=0, toString()=Message{topic='TopicTest', flag=0, properties={MIN_OFFSET=0, MAX_OFFSET=250, CONSUME_START_TIME=1775904266401, UNIQ_KEY=FD34DD838CB90000AC480E823DAC73A022B028D93B30378402C00172, CLUSTER=DefaultCluster, WAIT=true, TAGS=TagA}, body=[72, 101, 108, 108, 111, 32, 82, 111, 99, 107, 101, 116, 77, 81, 32, 51, 55, 48], transactionId='null'}]]
ConsumeMessageThread_5 Receive New Messages: [MessageExt [brokerName=broker-b, queueId=0, storeSize=227, queueOffset=169, sysFlag=0, bornTimestamp=1775904198308, bornHost=/192.168.2.148:33524, storeTimestamp=1775904198309, storeHost=/192.168.2.148:10911, msgId=C0A8029400002A9F00000000000259A8, commitLogOffset=154024, bodyCRC=120288705, reconsumeTimes=0, preparedTransactionOffset=0, toString()=Message{topic='TopicTest', flag=0, properties={MIN_OFFSET=0, MAX_OFFSET=250, CONSUME_START_TIME=1775904266390, UNIQ_KEY=FD34DD838CB90000AC480E823DAC73A022B028D93B30378402A40167, CLUSTER=DefaultCluster, WAIT=true, TAGS=TagA}, body=[72, 101, 108, 108, 111, 32, 82, 111, 99, 107, 101, 116, 77, 81, 32, 51, 53, 57], transactionId='null'}]]

关闭集群

RocketMQ 无论是关闭 NameServer 集群还是 Broker 集群,都可以使用 bin/mqshutdown 命令。

特别注意

在 RocketMQ 集群关闭的过程中,通常应该先关闭 Broker 集群,再关闭 NameServer 集群。因为 Broker 的运行依赖向 NameServer 注册路由信息,Producer 和 Consumer 也通过 NameServer 获取 Broker 地址列表;如果先关闭 NameServer,会导致路由获取和更新失败,可能引发生产者发送异常、消费者消费异常以及 Broker 心跳状态不一致等问题,而先关闭 Broker 可以让系统停止接收新消息并完成存量消费,最后再关闭 NameServer 则更安全、规范。

Broker 集群

在 Broker 所在的多台物理主机上(包括 rocketmq1rocketmq2),分别执行以下命令:

  • 关闭 Broker
1
2
3
4
5
# 进入 RocketMQ 的安装目录
cd rocketmq-all-4.9.0

# 关闭 Broker(Master + Slave)
sh bin/mqshutdown broker

NameServer 集群

在 NameServer 所在的多台物理主机上(包括 rocketmq1rocketmq2),分别执行以下命令:

  • 关闭 NameServer
1
2
3
4
5
# 进入 RocketMQ 的安装目录
cd rocketmq-all-4.9.0

# 关闭 NameServer
sh bin/mqshutdown namesrv

管理集群

在上述搭建的 RocketMQ 集群中,NameServer 和 Broker 服务都是通过 nohup 命令实现后台运行的,这种方式无法实现进程守护,也不支持开机自动启动和故障自动重启进程。为了解决这些问题,建议使用 Supervisor 对 NameServer 和 Broker 进程进行统一管理,以提升服务的稳定性和可运维性。首先关闭 RocketMQ 集群,然后安装并启动 Supervisor 服务(如下所示),最后添加相应的 Supervisor 配置文件来管理 NameServer 和 Broker 进程。

RocketMQ 自带的 mqadmin 管理工具

在 RocketMQ 的 bin 目录下有一个 mqadmin 管理工具,它是一个运维命令,用于对 RocketMQ 的集群、Topic、Broker 等信息进行管理,详细使用教程可以看 这里 的介绍。

准备工作

关闭 RocketMQ 集群

在所有物理主机上(包括 rocketmq1rocketmq2),分别执行以下命令:

  • 关闭 Broker 集群
1
2
3
4
5
# 进入 RocketMQ 的安装目录
cd rocketmq-all-4.9.0

# 关闭 Broker(Master + Slave)
sh bin/mqshutdown broker
  • 关闭 NameServer 集群
1
2
3
4
5
# 进入 RocketMQ 的安装目录
cd rocketmq-all-4.9.0

# 关闭 NameServer
sh bin/mqshutdown namesrv

Supervisor 安装

在所有物理主机上(包括 rocketmq1rocketmq2),分别执行以下命令:

  • CentOS、Fedora 安装 Supervisor
1
2
3
4
5
6
7
8
9
10
11
# 安装 Supervisor
sudo yum install -y supervisor

# 开机自动启动 Supervisor
sudo systemctl enable supervisord

# 启动 Supervisor
sudo systemctl start supervisord

# 查看 Supervisor 运行状态
sudo systemctl status supervisord
  • Debian、Ubuntu 安装 Supervisor
1
2
3
4
5
6
7
8
9
10
11
# 安装 Supervisor
sudo apt install -y supervisor

# 开机自动启动 Supervisor
sudo systemctl enable supervisor

# 启动 Supervisor
sudo systemctl start supervisor

# 查看 Supervisor 运行状态
sudo systemctl status supervisor

NameServer 集群

这里以 NameServer 集群的第一个节点为例,演示如何使用 Supervisor 来管理 NameServer 进程,其余 NameServer 节点的配置步骤相同,不再赘述。

  • 创建 Supervisor 配置文件
1
2
# 创建配置文件,写入以下配置内容
sudo vi /etc/supervisord.d/rocketmq-namesrv.ini
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
; 定义一个被 Supervisor 管理的程序,名称为 rocketmq-namesrv
[program:rocketmq-namesrv]
; 指定使用 rocketmq 用户启动进程(避免使用 root)
user=rocketmq
; 指定程序运行的工作目录
directory=/home/rocketmq/rocketmq-all-4.9.0
; 启动命令(通过 bash 执行 NameServer 启动脚本)
command=/bin/bash -c "sh /home/rocketmq/rocketmq-all-4.9.0/bin/mqnamesrv"
; 停止时向整个进程组(确保子进程如 Java 进程也被停止)
stopasgroup=true
; 强制终止整个进程组(确保子进程如 Java 进程也被杀掉)
killasgroup=true
; Supervisor 启动时自动启动该程序
autostart=true
; 程序异常退出后自动重启
autorestart=true
; 启动成功判定时间(运行超过 5 秒视为启动成功)
startsecs=5
; 启动失败最大重试次数
startretries=10
; 正常退出的状态码(0 表示正常退出)
exitcodes=0
; 停止程序时等待的最大时间(秒)
stopwaitsecs=60
; 标准输出日志的文件路径
stdout_logfile=/var/log/supervisor/rocketmq/logs/namesrv.out.log
; 单个标准输出日志文件的最大大小
stdout_logfile_maxbytes=50MB
; 标准输出日志文件最多保留多少个
stdout_logfile_backups=5
; 错误输出日志文件的路径
stderr_logfile=/var/log/supervisor/rocketmq/logs/namesrv.err.log
; 单个错误输出日志文件的最大大小
stderr_logfile_maxbytes=50MB
; 错误输出日志文件最多保留多少个
stderr_logfile_backups=5

NameServer 进程的关闭

在使用 Supervisor 管理 NameServer 进程时,不能使用 stopcommand=/bin/bash -c "sh /home/rocketmq/rocketmq-all-4.9.0/bin/mqshutdown namesrv" 配置内容来关闭 NameServer 进程,因为 mqshutdown namesrv 此命令会在当前物理主机上扫描 JVM 进程并关闭所有 NameServer 进程,无法区分具体 NameServer 实例,属于全局操作,不适用于多个 NameServer 实例的场景;应通过 Supervisor 自身的进程级控制实现单个 NameServer 的启停。

  • 创建 Supervisor 日志目录
1
2
3
4
5
# 创建日志目录
sudo mkdir -p /var/log/supervisor/rocketmq/logs

# 授权日志目录
sudo chown -R rocketmq:rocketmq /var/log/supervisor/rocketmq/logs
  • 重新加载 Supervisor 配置文件
1
2
3
4
5
# 重新读取 Supervisor 配置文件(不会立即生效)
sudo supervisorctl reread

# 根据最新的配置,加载新增或更新的程序(使配置生效)
sudo supervisorctl update
  • NameServer 常用管理命令
1
2
3
4
5
6
7
8
9
10
11
# 启动 NameServer
sudo supervisorctl start rocketmq-namesrv

# 关闭 NameServer
sudo supervisorctl stop rocketmq-namesrv

# 重启 NameServer
sudo supervisorctl restart rocketmq-namesrv

# 查看 NameServer 运行状态
sudo supervisorctl status
  • NameServer 查看日志信息
1
2
3
4
5
# 查看 NameServer 的运行日志信息
tail -f ~/logs/rocketmqlogs/namesrv.log

# 查看 NameServer 的错误日志信息
tail -f /var/log/supervisor/rocketmq/logs/namesrv.err.log

Broker 集群

这里以 Master Broker 1 节点为例,演示如何使用 Supervisor 来管理 Broker 进程,其余 Broker 节点的配置步骤与之类似(注意,不同 Broker 节点启动时使用的 Properties 配置文件是不一样的),不再赘述。值得注意的是,在为 Broker 各节点配置 Supervisor 管理时,必须优先配置并启动 2 个 Master 节点,再配置并启动 2 个 Slave 节点,以保证 Broker 集群主从关系的正确建立。

  • 创建 Supervisor 配置文件
1
2
# 创建配置文件,写入以下配置内容
sudo vi /etc/supervisord.d/rocketmq-broker-m1.ini
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
; 定义一个被 Supervisor 管理的程序,名称为 rocketmq-broker-m1
[program:rocketmq-broker-m1]
; 指定使用 rocketmq 用户启动进程(避免使用 root)
user=rocketmq
; 指定程序运行的工作目录
directory=/home/rocketmq/rocketmq-all-4.9.0
; 启动命令(通过 bash 执行 Broker 启动脚本),注意不同 Broker 节点启动时使用的配置文件是不一样的
command=/bin/bash -c "sh /home/rocketmq/rocketmq-all-4.9.0/bin/mqbroker -c /home/rocketmq/rocketmq-all-4.9.0/conf/2m-2s-async/broker-a.properties"
; 停止时向整个进程组(确保子进程如 Java 进程也被停止)
stopasgroup=true
; 强制终止整个进程组(确保子进程如 Java 进程也被杀掉)
killasgroup=true
; Supervisor 启动时自动启动该程序
autostart=true
; 程序异常退出后自动重启
autorestart=true
; 启动成功判定时间(运行超过 5 秒视为启动成功)
startsecs=5
; 启动失败最大重试次数
startretries=10
; 正常退出的状态码(0 表示正常退出)
exitcodes=0
; 停止程序时等待的最大时间(秒)
stopwaitsecs=60
; 标准输出日志的文件路径
stdout_logfile=/var/log/supervisor/rocketmq/logs/broker-m1.out.log
; 单个标准输出日志文件的最大大小
stdout_logfile_maxbytes=50MB
; 标准输出日志文件最多保留多少个
stdout_logfile_backups=5
; 错误输出日志文件的路径
stderr_logfile=/var/log/supervisor/rocketmq/logs/broker-m1.err.log
; 单个错误输出日志文件的最大大小
stderr_logfile_maxbytes=50MB
; 错误输出日志文件最多保留多少个
stderr_logfile_backups=5

Broker 进程的关闭

在使用 Supervisor 管理 Broker 进程时,不能使用 stopcommand=/bin/bash -c "sh /home/rocketmq/rocketmq-all-4.9.0/bin/mqshutdown broker" 配置内容来关闭 Broker 进程,因为 mqshutdown broker 此命令会在当前物理主机上扫描 JVM 进程并关闭所有 Broker 进程,无法区分具体 Broker 实例,属于全局操作,不适用于多个 Broker 实例的场景;应通过 Supervisor 自身的进程级控制实现单个 Broker 的启停。

  • 创建 Supervisor 日志目录
1
2
3
4
5
# 创建日志目录
sudo mkdir -p /var/log/supervisor/rocketmq/logs

# 授权日志目录
sudo chown -R rocketmq:rocketmq /var/log/supervisor/rocketmq/logs
  • 重新加载 Supervisor 配置文件
1
2
3
4
5
# 重新读取 Supervisor 配置文件(不会立即生效)
sudo supervisorctl reread

# 根据最新的配置,加载新增或更新的程序(使配置生效)
sudo supervisorctl update
  • Broker 常用管理命令
1
2
3
4
5
6
7
8
9
10
11
# 启动 Broker
sudo supervisorctl start rocketmq-broker-m1

# 关闭 Broker
sudo supervisorctl stop rocketmq-broker-m1

# 重启 Broker
sudo supervisorctl restart rocketmq-broker-m1

# 查看 Broker 运行状态
sudo supervisorctl status
  • Broker 查看日志信息
1
2
3
4
5
# 查看 Broker 的运行日志信息
tail -f ~/logs/rocketmqlogs/broker.log

# 查看 Broker 的错误日志信息
tail -f /var/log/supervisor/rocketmq/logs/broker-m1.err.log

其他 Broker 节点的 Supervisor 管理配置方式

其他 Broker 节点的 Supervisor 配置与 Master Broker 1 基本一致,通常只需要将上述配置和命令中的 broker-m1 替换为对应 Broker 节点的标识(比如 broker-m2),并将 -c /home/rocketmq/rocketmq-all-4.9.0/conf/2m-2s-async/broker-a.properties 中的 broker-a.properties 替换为该节点对应的配置文件(比如 broker-b.properties)即可。不同 Broker 节点对应的配置文件如下表所示:

物理主机序号 Broker 角色 Broker 标识配置文件
1Master Broker 1broker-m1rocketmq-all-4.9.0/conf/2m-2s-async/broker-a.properties
1Slave Broker 2broker-s2rocketmq-all-4.9.0/conf/2m-2s-async/broker-b-s.properties
2Master Broker 2broker-m2rocketmq-all-4.9.0/conf/2m-2s-async/broker-b.properties
2Slave Broker 1broker-s1rocketmq-all-4.9.0/conf/2m-2s-async/broker-a-s.properties
  • 最终在物理主机一(rocketmq1)上配置完 Supervisor 的进程管理后,执行 sudo supervisorctl status 命令输出的结果如下:
1
2
3
rocketmq-broker-m1               RUNNING   pid 8907, uptime 0:56:15
rocketmq-broker-s2 RUNNING pid 9460, uptime 0:26:04
rocketmq-namesrv RUNNING pid 9890, uptime 0:01:50
  • 最终在物理主机二(rocketmq2)上配置完 Supervisor 的进程管理后,执行 sudo supervisorctl status 命令输出的结果如下:
1
2
3
rocketmq-broker-m2               RUNNING   pid 7031, uptime 0:46:01
rocketmq-broker-s1 RUNNING pid 7692, uptime 0:10:14
rocketmq-namesrv RUNNING pid 7851, uptime 0:03:26

RocketMQ 控制台部署实战

RocketMQ Dashboard 是 RocketMQ 官方开发的管控利器,为用户提供客户端和应用程序的各种事件、性能的统计信息,支持以可视化工具代替 Topic 配置、Broker 管理等命令行操作,其核心功能如下表所示:

面板功能
运维修改 NamServer 地址;选用 VIPChannel
驾驶舱查看 Broker、Topic 消息量
集群集群分布,Broker 配置、运行信息
主题搜索、筛选、删除、更新 / 新增主题,消息路由,发送消息,重置消费位点
消费者搜索、删除、新增 / 更新消费者组,终端,消费详情,配置
消息消息记录,死信消息,消息轨迹等消息详情

特别注意

  • 以下所有操作,只需要在任意一台物理主机(比如 rocketmq1)上执行,无需在所有物理主机上重复执行
  • RocketMQ 控制台既可以与 NameServer 和 Broker 部署在同一台机器上,也可以独立部署在其他机器上。
  • RocketMQ 控制台通常只需部署一个实例,如果需要实现高可用,可以部署多个实例,并通过 Nginx 或 HAProxy 进行负载均衡。

准备工作

RocketMQ 控制台需要通过编译源码的方式来安装,因此需要提前安装 JDK 和 Maven。

JDK 版本说明

RocketMQ 控制台项目(1.0.0 版本)在编译阶段依赖 JDK 1.7(即使用 Java 7 语法和字节码版本进行编译),但在运行阶段兼容 JDK 1.7 及以上版本,因此可以正常运行在 JDK 1.8+ 环境中。

JDK 安装

JDK 手动安装

  • 下载并安装 JDK(1.7 版本)
1
2
3
4
5
6
7
8
# 下载文件(OpenJDK 1.7,Azul Zulu 发行版)
wget https://cdn.azul.com/zulu/bin/zulu7.56.0.11-ca-jdk7.0.352-linux_x64.tar.gz

# 解压文件
tar -zxvf zulu7.56.0.11-ca-jdk7.0.352-linux_x64.tar.gz

# 移动文件
sudo mv zulu7.56.0.11-ca-jdk7.0.352-linux_x64 /usr/local/jdk-7.0.352

全局环境变量配置

  • 配置系统环境变量
1
2
# 编辑系统配置文件,在文件末尾添加以下内容
sudo vi /etc/profile
1
2
export JAVA_HOME=/usr/local/jdk-7.0.352
export PATH=$JAVA_HOME/bin:$PATH
  • 让系统环境变量生效
1
sudo source /etc/profile

用户环境变量配置

1
2
# 切换至 rocketmq 用户
sudo -u rocketmq -s
1
2
# 编辑用户配置文件,在文件末尾添加以下内容
vi ~/.bashrc
1
2
export JAVA_HOME=/usr/local/jdk-7.0.352
export PATH=$JAVA_HOME/bin:$PATH
  • 让用户环境变量生效
1
source ~/.bashrc

验证 JDK 安装

1
java -version

Maven 安装

Maven 手动安装

  • 下载并安装 Maven
1
2
3
4
5
6
7
8
# 下载文件
wget https://archive.apache.org/dist/maven/maven-3/3.6.0/binaries/apache-maven-3.6.0-bin.tar.gz

# 解压文件
tar -zxvf apache-maven-3.6.0-bin.tar.gz

# 移动文件
sudo mv apache-maven-3.6.0 /usr/local/maven-3.6.0

全局环境变量配置

  • 配置系统环境变量
1
2
# 编辑系统配置文件,在文件末尾添加以下内容
sudo vi /etc/profile
1
2
export MAVEN_HOME=/usr/local/maven-3.6.0
export PATH=$MAVEN_HOME/bin:$PATH
  • 让系统环境变量生效
1
sudo source /etc/profile

用户环境变量配置

1
2
# 切换至 rocketmq 用户
sudo -u rocketmq -s
1
2
# 编辑用户配置文件,在文件末尾添加以下内容
vi ~/.bashrc
1
2
export MAVEN_HOME=/usr/local/maven-3.6.0
export PATH=$MAVEN_HOME/bin:$PATH
  • 让用户环境变量生效
1
source ~/.bashrc

验证 Maven 安装

1
mvn -version

软件下载

从 RocketMQ 官方的 GitHub Tags 下载控制台的源代码压缩包(比如 rocketmq-console-1.0.0.zip),如下图所示:

  • 下载文件
1
wget https://github.com/apache/rocketmq-externals/archive/refs/tags/rocketmq-console-1.0.0.zip
  • 解压文件
1
2
3
4
5
6
7
8
9
10
11
# 解压文件
unzip rocketmq-console-1.0.0.zip

# 移动目录
mv rocketmq-externals-rocketmq-console-1.0.0/rocketmq-console rocketmq-console-1.0.0

# 删除目录
rm -rf rocketmq-externals-rocketmq-console-1.0.0

# 进入解压目录
cd rocketmq-console-1.0.0

打包项目

  • 更改控制台的配置文件
1
2
# 编辑控制台的配置文件,更改以下内容
vi src/main/resources/application.properties
1
2
3
4
5
# 默认的端口号是 8080,将其更改为一个不常用的端口
server.port=7000

# 指定 RocketMQ 的 NameServer 地址列表,多个地址使用分号隔开
rocketmq.config.namesrvAddr=192.168.2.234:9876;192.168.2.148:9876
  • 添加 Maven 依赖项(JAXB)
1
2
# 编辑控制台的 Maven 配置文件,添加以下内容
vi pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>

JAXB 是什么

JAXB(Java Architechture for Xml Binding)用于 XML 绑定的 Java 技术,是一个业界标准,是一项可以根据 XML Schema 生成 Java 类的技术。

  • Maven 打包控制台项目
1
2
# 编译打包控制台项目
mvn clean package -Dmaven.test.skip=true

启动服务

  • 启动控制台
1
2
# 后台启动控制台
nohup java -jar target/rocketmq-console-ng-1.0.0.jar &

测试服务

  • 浏览器打开 http://192.168.2.234:7000 访问 RocketMQ 的控制台,请自行更改 IP 地址,默认端口号是 8080,如下图所示:


管理服务

上述部署的 RocketMQ 控制台是通过 nohup 命令实现后台运行的,这种方式无法实现进程守护,也不支持开机自动启动和故障自动重启进程。为了解决这些问题,建议使用 Supervisor 对 RocketMQ 控制台进程进行统一管理,以提升服务的稳定性和可运维性。首先安装并启动 Supervisor 服务(详细的安装步骤可以参考 这里),然后添加相应的 Supervisor 配置文件来管理 RocketMQ 控制台进程。

  • 创建 Supervisor 配置文件
1
2
# 创建配置文件,写入以下配置内容
sudo vi /etc/supervisord.d/rocketmq-console.ini
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
; 定义一个被 Supervisor 管理的程序,名称为 rocketmq-console
[program:rocketmq-console]
; 指定使用 rocketmq 用户启动进程(避免使用 root)
user=rocketmq
; 指定程序运行的工作目录
directory=/home/rocketmq/rocketmq-console-1.0.0
; 启动命令(通过 bash 执行 Broker 启动脚本)
command=java -jar /home/rocketmq/rocketmq-console-1.0.0/target/rocketmq-console-ng-1.0.0.jar
; 停止时向整个进程组(确保子进程如 Java 进程也被停止)
stopasgroup=true
; 强制终止整个进程组(确保子进程如 Java 进程也被杀掉)
killasgroup=true
; Supervisor 启动时自动启动该程序
autostart=true
; 程序异常退出后自动重启
autorestart=true
; 启动成功判定时间(运行超过 5 秒视为启动成功)
startsecs=5
; 启动失败最大重试次数
startretries=10
; 正常退出的状态码(0 表示正常退出)
exitcodes=0
; 停止程序时等待的最大时间(秒)
stopwaitsecs=60
; 标准输出日志的文件路径
stdout_logfile=/var/log/supervisor/rocketmq/logs/console.out.log
; 单个标准输出日志文件的最大大小
stdout_logfile_maxbytes=50MB
; 标准输出日志文件最多保留多少个
stdout_logfile_backups=5
; 错误输出日志文件的路径
stderr_logfile=/var/log/supervisor/rocketmq/logs/console.err.log
; 单个错误输出日志文件的最大大小
stderr_logfile_maxbytes=50MB
; 错误输出日志文件最多保留多少个
stderr_logfile_backups=5
  • 创建 Supervisor 日志目录
1
2
3
4
5
# 创建日志目录
sudo mkdir -p /var/log/supervisor/rocketmq/logs

# 授权日志目录
sudo chown -R rocketmq:rocketmq /var/log/supervisor/rocketmq/logs
  • 重新加载 Supervisor 配置文件
1
2
3
4
5
# 重新读取 Supervisor 配置文件(不会立即生效)
sudo supervisorctl reread

# 根据最新的配置,加载新增或更新的程序(使配置生效)
sudo supervisorctl update
  • RocketMQ 控制台常用管理命令
1
2
3
4
5
6
7
8
9
10
11
# 启动 RocketMQ 控制台
sudo supervisorctl start rocketmq-console

# 关闭 RocketMQ 控制台
sudo supervisorctl stop rocketmq-console

# 重启 RocketMQ 控制台
sudo supervisorctl restart rocketmq-console

# 查看 RocketMQ 控制台的运行状态
sudo supervisorctl status
  • RocketMQ 控制台查看日志信息
1
2
3
4
5
# 查看 RocketMQ 控制台的运行日志信息
tail -f /var/log/supervisor/rocketmq/logs/console.out.log

# 查看 RocketMQ 控制台的错误日志信息
tail -f /var/log/supervisor/rocketmq/logs/namesrv.err.log