RocketMQ集群部署与运维指南
RocketMQ集群部署与运维指南
集群架构概述
RocketMQ 集群由多个组件组成,包括 Name Server、Broker、Producer 和 Consumer。了解 RocketMQ 的集群架构对于正确部署和运维至关重要。
集群角色
1. Name Server 集群
Name Server 是一个无状态的服务发现和路由组件,负责管理 Topic 的路由信息。Name Server 集群中的各个节点之间不通信,每个 Name Server 都存储完整的路由信息。
特点:
- 无状态设计,可以随时扩缩容
- 各节点之间互不通信,独立工作
- Broker 会向所有 Name Server 注册路由信息
- 客户端可以连接任意一个 Name Server 获取路由信息
2. Broker 集群
Broker 负责消息的存储和转发,是 RocketMQ 的核心组件。Broker 集群支持多种部署模式,包括单 Master、多 Master、多 Master 多 Slave 等。
角色类型:
- Master:负责读写请求,可以部署多个 Master 形成集群
- Slave:负责从 Master 同步数据,提供读服务和容灾能力
复制模式:
- 同步复制:Master 向 Slave 同步数据完成后才返回成功响应给客户端
- 异步复制:Master 向 Slave 异步复制数据,不等待复制完成就返回成功响应给客户端
刷盘模式:
- 同步刷盘:消息写入磁盘后才返回成功响应
- 异步刷盘:消息写入内存后就返回成功响应,后台线程异步刷盘
集群模式
1. 单 Master 模式
单 Master 模式是最简单的部署方式,只部署一个 Master 节点,没有 Slave 节点。
优点:
- 部署简单,适合开发测试环境
缺点:
- 单点故障风险高,不适合生产环境
2. 多 Master 模式
多 Master 模式是指部署多个 Master 节点,每个 Master 负责不同的消息队列。
优点:
- 无单点故障风险
- 水平扩展能力强
缺点:
- Master 宕机期间,该节点上的消息不可用
- 消息可能丢失(如果是异步刷盘)
3. 多 Master 多 Slave 模式(异步复制)
多 Master 多 Slave 模式(异步复制)是指每个 Master 配置一个或多个 Slave,Master 和 Slave 之间采用异步复制方式同步数据。
优点:
- 高可用性,Master 宕机后,消费者可以从 Slave 读取消息
- 高性能,异步复制不影响 Master 的响应速度
缺点:
- 可能会有少量消息丢失(Master 宕机时未复制到 Slave 的消息)
4. 多 Master 多 Slave 模式(同步复制)
多 Master 多 Slave 模式(同步复制)是指每个 Master 配置一个或多个 Slave,Master 和 Slave 之间采用同步复制方式同步数据。
优点:
- 数据零丢失,Master 宕机后,Slave 上的数据是完整的
- 高可用性,Master 宕机后,消费者可以从 Slave 读取消息
缺点:
- 性能略低,同步复制会影响 Master 的响应速度
集群部署架构图

集群部署
1. 环境准备
1.1 硬件要求
Name Server:
- CPU:4核+
- 内存:4GB+
- 磁盘:50GB+
- 网络:千兆网卡
Broker:
- CPU:8核+
- 内存:16GB+
- 磁盘:500GB+ SSD(推荐)
- 网络:千兆网卡
1.2 软件要求
- 64位操作系统(Linux推荐)
- JDK 1.8+
- Maven 3.2.x+(如果需要编译源码)
2. 单机部署
2.1 下载安装包
# 下载二进制包
wget https://archive.apache.org/dist/rocketmq/4.9.4/rocketmq-all-4.9.4-bin-release.zip
# 解压
unzip rocketmq-all-4.9.4-bin-release.zip
cd rocketmq-4.9.4/
2.2 修改JVM参数
由于RocketMQ默认的JVM参数较大,需要根据实际情况调整。
# 修改Name Server启动脚本
vi bin/runserver.sh
# 将以下行修改为合适的值
JAVA_OPT="${JAVA_OPT} -server -Xms2g -Xmx2g -Xmn1g"
# 修改Broker启动脚本
vi bin/runbroker.sh
# 将以下行修改为合适的值
JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g"
2.3 启动Name Server
# 启动Name Server
nohup sh bin/mqnamesrv &
# 查看启动日志
tail -f ~/logs/rocketmqlogs/namesrv.log
2.4 配置并启动Broker
创建Broker配置文件:
# 创建配置文件目录
mkdir -p conf/broker-a
# 创建配置文件
vi conf/broker-a/broker.conf
添加以下配置:
# 集群名称
brokerClusterName=DefaultCluster
# Broker名称
brokerName=broker-a
# Broker ID,0表示Master,大于0表示Slave
brokerId=0
# 删除过期文件的时间点,默认凌晨4点
deleteWhen=04
# 文件保留时间,默认48小时
fileReservedTime=48
# Broker角色,ASYNC_MASTER表示异步复制Master
brokerRole=ASYNC_MASTER
# 刷盘策略,ASYNC_FLUSH表示异步刷盘
flushDiskType=ASYNC_FLUSH
# Name Server地址
nameServer=localhost:9876
# 存储路径
storePathRootDir=/home/rocketmq/store
# commitLog路径
storePathCommitLog=/home/rocketmq/store/commitlog
# 消费队列路径
storePathConsumeQueue=/home/rocketmq/store/consumequeue
# 索引路径
storePathIndex=/home/rocketmq/store/index
# checkpoint文件路径
storeCheckpoint=/home/rocketmq/store/checkpoint
# abort文件路径
abortFile=/home/rocketmq/store/abort
# 允许的最大消息大小,默认4MB
maxMessageSize=4194304
启动Broker:
# 创建存储目录
mkdir -p /home/rocketmq/store
# 启动Broker
nohup sh bin/mqbroker -c conf/broker-a/broker.conf &
# 查看启动日志
tail -f ~/logs/rocketmqlogs/broker.log
2.5 验证部署
# 使用mqadmin工具查看集群状态
sh bin/mqadmin clusterList -n localhost:9876
# 查看Topic列表
sh bin/mqadmin topicList -n localhost:9876
# 创建测试Topic
sh bin/mqadmin updateTopic -n localhost:9876 -c DefaultCluster -t TestTopic
3. 集群部署
3.1 多Master多Slave集群部署(异步复制)
假设我们有4台服务器,部署2主2从的集群架构:
角色 | IP地址 | 端口 |
---|---|---|
NameServer1 | 192.168.1.101 | 9876 |
NameServer2 | 192.168.1.102 | 9876 |
BrokerMaster1 | 192.168.1.103 | 10911 |
BrokerSlave1 | 192.168.1.104 | 10911 |
BrokerMaster2 | 192.168.1.105 | 10911 |
BrokerSlave2 | 192.168.1.106 | 10911 |
3.1.1 部署NameServer
在192.168.1.101和192.168.1.102上执行:
# 启动NameServer
nohup sh bin/mqnamesrv &
3.1.2 部署BrokerMaster1
在192.168.1.103上创建配置文件conf/broker-a/broker.conf
:
brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=0
deleteWhen=04
fileReservedTime=48
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH
nameServer=192.168.1.101:9876;192.168.1.102:9876
listenPort=10911
storePathRootDir=/home/rocketmq/store
storePathCommitLog=/home/rocketmq/store/commitlog
storePathConsumeQueue=/home/rocketmq/store/consumequeue
storePathIndex=/home/rocketmq/store/index
storeCheckpoint=/home/rocketmq/store/checkpoint
abortFile=/home/rocketmq/store/abort
maxMessageSize=4194304
启动BrokerMaster1:
nohup sh bin/mqbroker -c conf/broker-a/broker.conf &
3.1.3 部署BrokerSlave1
在192.168.1.104上创建配置文件conf/broker-a/broker.conf
:
brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=1
deleteWhen=04
fileReservedTime=48
brokerRole=SLAVE
flushDiskType=ASYNC_FLUSH
nameServer=192.168.1.101:9876;192.168.1.102:9876
listenPort=10911
storePathRootDir=/home/rocketmq/store
storePathCommitLog=/home/rocketmq/store/commitlog
storePathConsumeQueue=/home/rocketmq/store/consumequeue
storePathIndex=/home/rocketmq/store/index
storeCheckpoint=/home/rocketmq/store/checkpoint
abortFile=/home/rocketmq/store/abort
maxMessageSize=4194304
启动BrokerSlave1:
nohup sh bin/mqbroker -c conf/broker-a/broker.conf &
3.1.4 部署BrokerMaster2
在192.168.1.105上创建配置文件conf/broker-b/broker.conf
:
brokerClusterName=DefaultCluster
brokerName=broker-b
brokerId=0
deleteWhen=04
fileReservedTime=48
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH
nameServer=192.168.1.101:9876;192.168.1.102:9876
listenPort=10911
storePathRootDir=/home/rocketmq/store
storePathCommitLog=/home/rocketmq/store/commitlog
storePathConsumeQueue=/home/rocketmq/store/consumequeue
storePathIndex=/home/rocketmq/store/index
storeCheckpoint=/home/rocketmq/store/checkpoint
abortFile=/home/rocketmq/store/abort
maxMessageSize=4194304
启动BrokerMaster2:
nohup sh bin/mqbroker -c conf/broker-b/broker.conf &
3.1.5 部署BrokerSlave2
在192.168.1.106上创建配置文件conf/broker-b/broker.conf
:
brokerClusterName=DefaultCluster
brokerName=broker-b
brokerId=1
deleteWhen=04
fileReservedTime=48
brokerRole=SLAVE
flushDiskType=ASYNC_FLUSH
nameServer=192.168.1.101:9876;192.168.1.102:9876
listenPort=10911
storePathRootDir=/home/rocketmq/store
storePathCommitLog=/home/rocketmq/store/commitlog
storePathConsumeQueue=/home/rocketmq/store/consumequeue
storePathIndex=/home/rocketmq/store/index
storeCheckpoint=/home/rocketmq/store/checkpoint
abortFile=/home/rocketmq/store/abort
maxMessageSize=4194304
启动BrokerSlave2:
nohup sh bin/mqbroker -c conf/broker-b/broker.conf &
3.1.6 验证集群部署
# 查看集群状态
sh bin/mqadmin clusterList -n 192.168.1.101:9876
4. Docker部署
4.1 单机Docker部署
# 拉取镜像
docker pull apache/rocketmq:4.9.4
# 创建网络
docker network create rocketmq
# 创建数据卷
docker volume create rocketmq-namesrv-data
docker volume create rocketmq-broker-data
# 启动Name Server
docker run -d --name rmqnamesrv \
--network rocketmq \
-p 9876:9876 \
-v rocketmq-namesrv-data:/home/rocketmq/data \
apache/rocketmq:4.9.4 sh mqnamesrv
# 创建Broker配置文件
mkdir -p /tmp/rocketmq/conf
cat > /tmp/rocketmq/conf/broker.conf << EOF
brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=0
deleteWhen=04
fileReservedTime=48
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH
nameServer=rmqnamesrv:9876
EOF
# 启动Broker
docker run -d --name rmqbroker \
--network rocketmq \
-p 10909:10909 -p 10911:10911 \
-v rocketmq-broker-data:/home/rocketmq/data \
-v /tmp/rocketmq/conf/broker.conf:/home/rocketmq/conf/broker.conf \
apache/rocketmq:4.9.4 sh mqbroker -c /home/rocketmq/conf/broker.conf
4.2 Docker Compose部署
创建docker-compose.yml
文件:
docker-compose.yml
version: '3.9'
services:
namesrv1:
image: apache/rocketmq:4.9.4
container_name: rmqnamesrv1
ports:
- 9876:9876
volumes:
- ./data/namesrv1/logs:/home/rocketmq/logs
- ./data/namesrv1/data:/home/rocketmq/data
command: sh mqnamesrv
networks:
- rocketmq
namesrv2:
image: apache/rocketmq:4.9.4
container_name: rmqnamesrv2
ports:
- 9877:9876
volumes:
- ./data/namesrv2/logs:/home/rocketmq/logs
- ./data/namesrv2/data:/home/rocketmq/data
command: sh mqnamesrv
networks:
- rocketmq
broker-a-master:
image: apache/rocketmq:4.9.4
container_name: rmqbroker-a-master
ports:
- 10909:10909
- 10911:10911
volumes:
- ./data/broker-a-master/logs:/home/rocketmq/logs
- ./data/broker-a-master/data:/home/rocketmq/data
- ./conf/broker-a-master.conf:/home/rocketmq/conf/broker.conf
command: sh mqbroker -c /home/rocketmq/conf/broker.conf
depends_on:
- namesrv1
- namesrv2
networks:
- rocketmq
broker-a-slave:
image: apache/rocketmq:4.9.4
container_name: rmqbroker-a-slave
ports:
- 10919:10909
- 10921:10911
volumes:
- ./data/broker-a-slave/logs:/home/rocketmq/logs
- ./data/broker-a-slave/data:/home/rocketmq/data
- ./conf/broker-a-slave.conf:/home/rocketmq/conf/broker.conf
command: sh mqbroker -c /home/rocketmq/conf/broker.conf
depends_on:
- namesrv1
- namesrv2
- broker-a-master
networks:
- rocketmq
broker-b-master:
image: apache/rocketmq:4.9.4
container_name: rmqbroker-b-master
ports:
- 10929:10909
- 10931:10911
volumes:
- ./data/broker-b-master/logs:/home/rocketmq/logs
- ./data/broker-b-master/data:/home/rocketmq/data
- ./conf/broker-b-master.conf:/home/rocketmq/conf/broker.conf
command: sh mqbroker -c /home/rocketmq/conf/broker.conf
depends_on:
- namesrv1
- namesrv2
networks:
- rocketmq
broker-b-slave:
image: apache/rocketmq:4.9.4
container_name: rmqbroker-b-slave
ports:
- 10939:10909
- 10941:10911
volumes:
- ./data/broker-b-slave/logs:/home/rocketmq/logs
- ./data/broker-b-slave/data:/home/rocketmq/data
- ./conf/broker-b-slave.conf:/home/rocketmq/conf/broker.conf
command: sh mqbroker -c /home/rocketmq/conf/broker.conf
depends_on:
- namesrv1
- namesrv2
- broker-b-master
networks:
- rocketmq
dashboard:
image: apacherocketmq/rocketmq-dashboard:1.0.0
container_name: rmqdashboard
ports:
- 8080:8080
environment:
- JAVA_OPTS=-Drocketmq.namesrv.addr=namesrv1:9876;namesrv2:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false
depends_on:
- namesrv1
- namesrv2
networks:
- rocketmq
networks:
rocketmq:
driver: bridge
创建Broker配置文件:
mkdir -p conf
# broker-a-master.conf
cat > conf/broker-a-master.conf << EOF
brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=0
deleteWhen=04
fileReservedTime=48
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH
nameServer=namesrv1:9876;namesrv2:9876
EOF
# broker-a-slave.conf
cat > conf/broker-a-slave.conf << EOF
brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=1
deleteWhen=04
fileReservedTime=48
brokerRole=SLAVE
flushDiskType=ASYNC_FLUSH
nameServer=namesrv1:9876;namesrv2:9876
EOF
# broker-b-master.conf
cat > conf/broker-b-master.conf << EOF
brokerClusterName=DefaultCluster
brokerName=broker-b
brokerId=0
deleteWhen=04
fileReservedTime=48
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH
nameServer=namesrv1:9876;namesrv2:9876
EOF
# broker-b-slave.conf
cat > conf/broker-b-slave.conf << EOF
brokerClusterName=DefaultCluster
brokerName=broker-b
brokerId=1
deleteWhen=04
fileReservedTime=48
brokerRole=SLAVE
flushDiskType=ASYNC_FLUSH
nameServer=namesrv1:9876;namesrv2:9876
EOF
启动集群:
docker-compose up -d
5. Kubernetes部署
5.1 使用Helm部署
# 添加Helm仓库
helm repo add rocketmq-operator https://apache.github.io/rocketmq-operator/
# 更新仓库
helm repo update
# 安装RocketMQ Operator
helm install rocketmq rocketmq-operator/rocketmq-operator
# 创建RocketMQ集群配置文件
cat > rocketmq-cluster.yaml << EOF
apiVersion: rocketmq.apache.org/v1alpha1
kind: Cluster
metadata:
name: rocketmq-cluster
spec:
nameServers:
size: 2
image: apache/rocketmq:4.9.4
resources:
requests:
memory: "2Gi"
cpu: "500m"
limits:
memory: "4Gi"
cpu: "1000m"
brokers:
- name: broker-a
size: 2
image: apache/rocketmq:4.9.4
resources:
requests:
memory: "4Gi"
cpu: "1000m"
limits:
memory: "8Gi"
cpu: "2000m"
config:
brokerRole: ASYNC_MASTER
deleteWhen: "04"
fileReservedTime: "48"
flushDiskType: ASYNC_FLUSH
- name: broker-b
size: 2
image: apache/rocketmq:4.9.4
resources:
requests:
memory: "4Gi"
cpu: "1000m"
limits:
memory: "8Gi"
cpu: "2000m"
config:
brokerRole: ASYNC_MASTER
deleteWhen: "04"
fileReservedTime: "48"
flushDiskType: ASYNC_FLUSH
EOF
# 创建RocketMQ集群
kubectl apply -f rocketmq-cluster.yaml
集群监控
1. RocketMQ Dashboard
RocketMQ Dashboard 是 RocketMQ 官方提供的可视化管理工具,可以用来监控和管理 RocketMQ 集群。
1.1 部署 RocketMQ Dashboard
# 拉取镜像
docker pull apacherocketmq/rocketmq-dashboard:1.0.0
# 启动 Dashboard
docker run -d --name rmqdashboard \
-p 8080:8080 \
-e "JAVA_OPTS=-Drocketmq.namesrv.addr=192.168.1.101:9876;192.168.1.102:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false" \
apacherocketmq/rocketmq-dashboard:1.0.0
1.2 Dashboard 功能
- 集群监控:查看集群状态、Broker 状态等
- Topic 管理:创建、修改、删除 Topic,查看 Topic 详情
- 消费者管理:查看消费者组、消费进度等
- 消息查询:根据 Topic、Key、时间等条件查询消息
- 消息轨迹:查看消息从生产到消费的完整链路
2. Prometheus + Grafana 监控
2.1 配置 RocketMQ 暴露 Prometheus 指标
修改 Broker 配置文件,添加以下配置:
# 开启 Prometheus 监控
enablePrometheusEpoll=true
2.2 部署 Prometheus
创建 Prometheus 配置文件 prometheus.yml
:
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'rocketmq'
static_configs:
- targets: ['192.168.1.103:10911', '192.168.1.104:10911', '192.168.1.105:10911', '192.168.1.106:10911']
使用 Docker 启动 Prometheus:
docker run -d --name prometheus \
-p 9090:9090 \
-v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus
2.3 部署 Grafana
docker run -d --name grafana \
-p 3000:3000 \
grafana/grafana
2.4 配置 Grafana 数据源和仪表盘
- 访问 Grafana(http://localhost:3000),默认用户名和密码都是 admin
- 添加 Prometheus 数据源
- 导入 RocketMQ 仪表盘模板
3. 监控指标
3.1 系统指标
- CPU 使用率
- 内存使用率
- 磁盘 I/O
- 网络 I/O
3.2 RocketMQ 指标
Broker 指标:
- TPS(每秒事务数)
- 消息大小
- 消息延迟
- 磁盘使用率
- 堆内存使用率
Topic 指标:
- 生产 TPS
- 消费 TPS
- 消息堆积量
消费者指标:
- 消费延迟
- 消费失败率
- 重试次数
4. 告警配置
4.1 Prometheus 告警规则
创建告警规则文件 alert_rules.yml
:
groups:
- name: rocketmq_alerts
rules:
- alert: BrokerHighCpuUsage
expr: rate(process_cpu_seconds_total{job="rocketmq"}[5m]) * 100 > 80
for: 5m
labels:
severity: warning
annotations:
summary: "Broker CPU usage high (instance {{ $labels.instance }})"
description: "Broker CPU usage is above 80% for 5 minutes\n VALUE = {{ $value }}\n LABELS: {{ $labels }}"
- alert: BrokerHighMemoryUsage
expr: process_resident_memory_bytes{job="rocketmq"} / on(instance) node_memory_MemTotal_bytes * 100 > 80
for: 5m
labels:
severity: warning
annotations:
summary: "Broker memory usage high (instance {{ $labels.instance }})"
description: "Broker memory usage is above 80% for 5 minutes\n VALUE = {{ $value }}\n LABELS: {{ $labels }}"
- alert: BrokerHighDiskUsage
expr: node_filesystem_avail_bytes{job="rocketmq",mountpoint="/"} / node_filesystem_size_bytes{job="rocketmq",mountpoint="/"} * 100 < 20
for: 5m
labels:
severity: warning
annotations:
summary: "Broker disk usage high (instance {{ $labels.instance }})"
description: "Broker disk usage is above 80% for 5 minutes\n VALUE = {{ $value }}\n LABELS: {{ $labels }}"
- alert: MessageAccumulation
expr: rocketmq_consumer_lag > 10000
for: 5m
labels:
severity: warning
annotations:
summary: "Message accumulation (instance {{ $labels.instance }})"
description: "Message accumulation detected\n VALUE = {{ $value }}\n LABELS: {{ $labels }}"
4.2 配置 Alertmanager
创建 Alertmanager 配置文件 alertmanager.yml
:
global:
resolve_timeout: 5m
route:
group_by: ['alertname', 'instance']
group_wait: 30s
group_interval: 5m
repeat_interval: 1h
receiver: 'email-notifications'
receivers:
- name: 'email-notifications'
email_configs:
- to: 'admin@example.com'
from: 'alertmanager@example.com'
smarthost: 'smtp.example.com:587'
auth_username: 'alertmanager@example.com'
auth_password: 'password'
使用 Docker 启动 Alertmanager:
docker run -d --name alertmanager \
-p 9093:9093 \
-v /path/to/alertmanager.yml:/etc/alertmanager/alertmanager.yml \
prom/alertmanager
集群运维
1. 日常运维
1.1 Topic 管理
# 创建 Topic
sh bin/mqadmin updateTopic -n 192.168.1.101:9876 -c DefaultCluster -t TestTopic
# 查看 Topic 列表
sh bin/mqadmin topicList -n 192.168.1.101:9876
# 查看 Topic 状态
sh bin/mqadmin topicStatus -n 192.168.1.101:9876 -t TestTopic
# 删除 Topic
sh bin/mqadmin deleteTopic -n 192.168.1.101:9876 -c DefaultCluster -t TestTopic
1.2 消费者组管理
# 查看消费者组列表
sh bin/mqadmin consumerList -n 192.168.1.101:9876
# 查看消费者组状态
sh bin/mqadmin consumerStatus -n 192.168.1.101:9876 -g ConsumerGroup
# 查看消费者组订阅关系
sh bin/mqadmin consumerConnection -n 192.168.1.101:9876 -g ConsumerGroup
1.3 消息查询
# 根据消息ID查询消息
sh bin/mqadmin queryMsgById -n 192.168.1.101:9876 -i "0A9A003700002A9F000000000001CE97"
# 根据Key查询消息
sh bin/mqadmin queryMsgByKey -n 192.168.1.101:9876 -t TestTopic -k "TestKey"
# 根据时间查询消息
sh bin/mqadmin printMsg -n 192.168.1.101:9876 -t TestTopic -b 2021-01-01#00:00:00:000 -e 2021-01-02#00:00:00:000
1.4 集群管理
# 查看集群状态
sh bin/mqadmin clusterList -n 192.168.1.101:9876
# 查看Broker状态
sh bin/mqadmin brokerStatus -n 192.168.1.101:9876 -b 192.168.1.103:10911
# 更新Broker配置
sh bin/mqadmin updateBrokerConfig -n 192.168.1.101:9876 -b 192.168.1.103:10911 -k maxMessageSize -v 8388608
2. 扩容与缩容
2.1 扩容 Name Server
# 在新节点上启动 Name Server
nohup sh bin/mqnamesrv &
# 更新客户端配置,添加新的 Name Server 地址
nameServer=192.168.1.101:9876;192.168.1.102:9876;192.168.1.107:9876
2.2 扩容 Broker
# 在新节点上创建配置文件
vi conf/broker-c/broker.conf
# 添加配置
brokerClusterName=DefaultCluster
brokerName=broker-c
brokerId=0
deleteWhen=04
fileReservedTime=48
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH
nameServer=192.168.1.101:9876;192.168.1.102:9876
# 启动新的 Broker
nohup sh bin/mqbroker -c conf/broker-c/broker.conf &
2.3 缩容 Broker
# 1. 停止消息写入
# 将 Broker 设置为禁止写入状态
sh bin/mqadmin updateBrokerConfig -n 192.168.1.101:9876 -b 192.168.1.105:10911 -k disableProducer -v true
# 2. 等待消息消费完毕
# 查看消费进度
sh bin/mqadmin consumerProgress -n 192.168.1.101:9876
# 3. 停止 Broker
sh bin/mqshutdown broker
3. 数据迁移
3.1 使用 mqadmin 工具迁移数据
# 1. 创建迁移计划
sh bin/mqadmin topicClusterMigrate -n 192.168.1.101:9876 -t TestTopic -s DefaultCluster -c NewCluster
# 2. 执行迁移
sh bin/mqadmin topicClusterMigrate -n 192.168.1.101:9876 -t TestTopic -s DefaultCluster -c NewCluster -o execute
# 3. 查看迁移状态
sh bin/mqadmin topicClusterMigrate -n 192.168.1.101:9876 -t TestTopic -s DefaultCluster -c NewCluster -o status
4. 灾备与恢复
4.1 数据备份
# 停止 Broker
sh bin/mqshutdown broker
# 备份存储目录
tar -czvf rocketmq_backup_$(date +%Y%m%d).tar.gz /home/rocketmq/store
# 启动 Broker
nohup sh bin/mqbroker -c conf/broker-a/broker.conf &
4.2 数据恢复
# 停止 Broker
sh bin/mqshutdown broker
# 恢复存储目录
rm -rf /home/rocketmq/store
tar -xzvf rocketmq_backup_20210101.tar.gz -C /
# 启动 Broker
nohup sh bin/mqbroker -c conf/broker-a/broker.conf &
5. 性能调优
5.1 JVM 调优
修改 bin/runbroker.sh
文件:
JAVA_OPT="${JAVA_OPT} -server -Xms8g -Xmx8g -Xmn4g"
JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30"
JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m"
JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow"
JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch"
JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=15g"
5.2 操作系统调优
# 修改系统限制
cat > /etc/security/limits.conf << EOF
* soft nofile 65536
* hard nofile 65536
* soft nproc 131072
* hard nproc 131072
EOF
# 修改内核参数
cat > /etc/sysctl.conf << EOF
net.core.somaxconn=32768
net.core.netdev_max_backlog=65536
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_max_syn_backlog=8096
net.ipv4.tcp_wmem=4096 65536 16777216
net.ipv4.tcp_rmem=4096 65536 16777216
net.ipv4.tcp_slow_start_after_idle=0
vm.max_map_count=262144
vm.swappiness=10
EOF
# 应用配置
sysctl -p
5.3 Broker 参数调优
# 异步刷盘,提高性能
flushDiskType=ASYNC_FLUSH
# 异步复制,提高性能
brokerRole=ASYNC_MASTER
# 增加发送消息线程池大小
sendMessageThreadPoolNums=32
# 增加处理消息线程池大小
processReplyMessageThreadPoolNums=32
# 增加拉取消息线程池大小
pullMessageThreadPoolNums=32
# 增加查询消息线程池大小
queryMessageThreadPoolNums=32
# 增加客户端管理线程池大小
clientManageThreadPoolNums=32
# 增加管理线程池大小
adminBrokerThreadPoolNums=32
# 增加消费者管理线程池大小
consumerManageThreadPoolNums=32
# 增加心跳线程池大小
heartbeatThreadPoolNums=32
# 增加事务线程池大小
endTransactionThreadPoolNums=32
# 增加传输数据缓冲区大小
transferMsgByHeap=false
tranceTransactionMsgByHeap=false
# 增加 PageCache 锁定内存
lockInStrictMode=true
# 增加 CommitLog 刷盘间隔,减少 I/O 次数
flushIntervalCommitLog=500
# 增加 ConsumeQueue 刷盘间隔,减少 I/O 次数
flushIntervalConsumeQueue=1000
常见问题与解决方案
1. Broker 无法启动
问题:Broker 启动失败,日志中显示端口被占用。
解决方案:
# 查看端口占用情况
netstat -anp | grep 10911
# 杀死占用端口的进程
kill -9 <PID>
# 修改 Broker 配置,使用不同的端口
vi conf/broker.conf
listenPort=10912
2. 消息堆积
问题:消息在 Broker 中堆积,消费者消费速度跟不上生产速度。
解决方案:
- 增加消费者实例数量
- 优化消费者代码,提高处理效率
- 增加消费者线程数
// 增加消费者线程数
consumer.setConsumeThreadMin(20);
consumer.setConsumeThreadMax(50);
// 增加批量消费数量
consumer.setConsumeMessageBatchMaxSize(32);
3. 磁盘空间不足
问题:Broker 所在服务器磁盘空间不足,导致无法写入新消息。
解决方案:
- 清理过期日志文件
# 手动删除过期文件
rm -rf /home/rocketmq/store/commitlog/00000000000000000000
# 修改文件保留时间
vi conf/broker.conf
fileReservedTime=24
- 增加磁盘空间
# 挂载新磁盘
mkdir -p /data/rocketmq
mount /dev/sdb1 /data/rocketmq
# 修改存储路径
vi conf/broker.conf
storePathRootDir=/data/rocketmq/store
4. 消息丢失
问题:消息发送成功,但消费者没有收到消息。
解决方案:
- 开启同步刷盘和同步复制
# 同步刷盘
flushDiskType=SYNC_FLUSH
# 同步复制
brokerRole=SYNC_MASTER
- 生产者使用同步发送并设置重试
// 设置重试次数
producer.setRetryTimesWhenSendFailed(5);
// 使用同步发送
SendResult sendResult = producer.send(message);
- 消费者确认消费成功后再提交消费位点
try {
// 处理消息
// ...
// 处理成功后返回 CONSUME_SUCCESS
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
} catch (Exception e) {
// 处理失败,稍后重试
return ConsumeConcurrentlyStatus.RECONSUME_LATER;
}
5. 性能问题
问题:RocketMQ 性能不佳,TPS 较低。
解决方案:
- 调整 JVM 参数
JAVA_OPT="${JAVA_OPT} -server -Xms16g -Xmx16g -Xmn8g -XX:+UseG1GC"
- 使用异步刷盘和异步复制
flushDiskType=ASYNC_FLUSH
brokerRole=ASYNC_MASTER
- 使用 SSD 存储
storePathRootDir=/ssd/rocketmq/store
- 调整操作系统参数
sysctl -w vm.max_map_count=262144
sysctl -w vm.swappiness=10
最佳实践
1. 集群部署最佳实践
- 使用多 Master 多 Slave 架构,提高可用性
- Name Server 至少部署 2 个节点,避免单点故障
- 根据业务量合理规划 Broker 数量和规格
- 生产环境使用物理机或高性能云服务器
- 使用 SSD 存储提高 I/O 性能
2. 监控告警最佳实践
- 监控系统资源:CPU、内存、磁盘、网络
- 监控 RocketMQ 指标:TPS、消息堆积、消费延迟
- 设置合理的告警阈值,避免误报
- 建立完善的告警通知机制,支持邮件、短信、钉钉等多种通知方式
- 定期检查监控系统,确保监控正常运行
3. 运维管理最佳实践
- 制定完善的变更流程,重要变更提前评估风险
- 定期备份重要数据,如 Topic 配置、消费者组配置等
- 建立运维文档,记录部署架构、配置参数、操作流程等
- 定期进行容量规划,提前扩容,避免资源不足
- 建立故障演练机制,提高应对突发故障的能力
4. 安全防护最佳实践
- 启用 ACL 访问控制,限制客户端访问权限
- 使用 SSL/TLS 加密传输,保护数据安全
- 部署在内网环境,避免直接暴露在公网
- 定期更新 RocketMQ 版本,修复安全漏洞
- 定期审计访问日志,发现异常访问
总结
本文详细介绍了 RocketMQ 的集群部署和运维:
- ✅ 集群架构:Name Server 集群、Broker 集群、集群模式
- ✅ 集群部署:单机部署、集群部署、Docker 部署、Kubernetes 部署
- ✅ 集群监控:RocketMQ Dashboard、Prometheus + Grafana 监控、监控指标、告警配置
- ✅ 集群运维:日常运维、扩容与缩容、数据迁移、灾备与恢复、性能调优
- ✅ 常见问题与解决方案:Broker 无法启动、消息堆积、磁盘空间不足、消息丢失、性能问题
- ✅ 最佳实践:集群部署最佳实践、监控告警最佳实践、运维管理最佳实践、安全防护最佳实践
下一步学习
- 学习 RocketMQ 的源码分析
- 了解 RocketMQ 的性能测试方法
- 探索 RocketMQ 在大规模分布式系统中的应用
希望这篇文章能帮助您更好地部署和运维 RocketMQ 集群!如果您有任何问题,欢迎在评论区讨论。