这里写自定义目录标题
-
- 摘要
- 检查状态
-
- [1. 检查 RabbitMQ 服务状态](#1. 检查 RabbitMQ 服务状态)
- [2. 检查 RabbitMQ 端口监听](#2. 检查 RabbitMQ 端口监听)
- [3. 检查 RabbitMQ 管理插件是否启用](#3. 检查 RabbitMQ 管理插件是否启用)
- [4. 检查开机自启状态](#4. 检查开机自启状态)
- [5. 确认集群高可用性](#5. 确认集群高可用性)
- [6. 检查使用该集群的服务是否做了断开重连](#6. 检查使用该集群的服务是否做了断开重连)
- 实操
- 命令说明
-
- [查看集群状态命令 rabbitmqctl cluster_status](#查看集群状态命令 rabbitmqctl cluster_status)
- [查看节点同步状态 rabbitmqctl list_queues name pid slave_pids synchronised_slave_pids](#查看节点同步状态 rabbitmqctl list_queues name pid slave_pids synchronised_slave_pids)
- 删除队列
-
- [在 RabbitMQ 中执行删除队列(`delete_queue`)操作时,如果出现 `Access refused` 错误,通常是由于权限问题导致的。以下是可能的原因及解决方法:](#在 RabbitMQ 中执行删除队列(
delete_queue
)操作时,如果出现Access refused
错误,通常是由于权限问题导致的。以下是可能的原因及解决方法:)
- [在 RabbitMQ 中执行删除队列(`delete_queue`)操作时,如果出现 `Access refused` 错误,通常是由于权限问题导致的。以下是可能的原因及解决方法:](#在 RabbitMQ 中执行删除队列(
摘要
背景 :2025年云成本优化仍是技术团队的核心命题。当前需对遗留架构进行精细化治理,其中由前任架构师设计的RabbitMQ集群成为重点优化对象。该集群采用经典高可用架构,由3台阿里云ECS实例构成核心节点,并通过负载均衡(SLB)实现流量分发。然而,经监控分析发现,节点资源利用率长期低于40%,存在显著的配置冗余。在保障业务连续性的前提下,需通过降配调优实现成本节约。
ECS 配置 :8C16G,CPU利用率 峰值18%, 内存峰值 25%
降配目标 :平滑的将ECS节点降配至 2C8G
检查状态
1. 检查 RabbitMQ 服务状态
使用 systemctl
命令查看服务是否正在运行:
bash
sudo systemctl status rabbitmq-server
- 输出结果 :
- 如果显示
active (running)
,表示服务已启动。 - 如果显示
inactive (dead)
,表示服务未运行。
- 如果显示
2. 检查 RabbitMQ 端口监听
RabbitMQ 默认监听 5672
(AMQP 协议)和 15672
(管理界面)端口:
bash
# 使用 netstat 或 ss 命令检查端口
sudo netstat -tuln | grep -E '5672|15672'
# 或
sudo ss -tuln | grep -E '5672|15672'
- 输出结果 :如果有
LISTEN
状态的端口,说明服务正常。
3. 检查 RabbitMQ 管理插件是否启用
若需通过 Web 界面管理 RabbitMQ,需确认管理插件是否启用:
bash
sudo rabbitmq-plugins list
- 输出结果 :查找
rabbitmq_management
是否标记为[E*]
(已启用)。
4. 检查开机自启状态
确认 RabbitMQ 是否设置为开机自启:
bash
sudo systemctl is-enabled rabbitmq-server
- 输出结果 :
enabled
:已设置开机自启。disabled
:未设置开机自启(可通过sudo systemctl enable rabbitmq-server
启用)。
5. 确认集群高可用性
-
镜像队列配置 :确保所有业务队列已配置镜像策略(如
ha-mode: all
或指定副本数),避免单节点故障导致消息丢失。bash# 查看当前策略 rabbitmqctl list_policies # 示例:设置所有队列在3个节点镜像 rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
-
集群状态健康 :确认所有节点状态为
running
,且无网络分区问题。bashrabbitmqctl cluster_status
6. 检查使用该集群的服务是否做了断开重连
实操
1. 负载均衡配置
- 设置待降配节点的权重:在负载均衡(如 SLB)中暂时设置待操作节点的流量权重为0,确保降配期间流量仅路由到其他节点。
2. 逐个节点降配(滚动操作)
2.1 停止 RabbitMQ 服务
bash
sudo systemctl stop rabbitmq-server
-
验证节点离线 :检查集群状态,确认该节点已标记为
down
。bashrabbitmqctl cluster_status
2.2 调整 ECS 配置
- 关机 ECS
- 降配操作:通过 ECS 控制台或 API 调整实例规格(CPU/内存)。
- 重启 ECS(如需):若配置变更需要重启,确保重启后网络和存储正常挂载。
2.3 恢复节点并重新加入集群
-
启动 RabbitMQ :
bashsudo systemctl start rabbitmq-server
-
重新加入集群 :如果节点因 IP 或主机名变化无法自动加入,需手动操作(一般不需要重新加入)
bash# 在新节点上重置 RabbitMQ 并重新加入集群 rabbitmqctl stop_app rabbitmqctl reset rabbitmqctl join_cluster rabbit@<主节点主机名> rabbitmqctl start_app
-
验证集群状态 :确保节点状态为
running
,且队列镜像同步完成。
2.4 恢复负载均衡流量
- 将节点权重恢复,观察健康检查状态。
3. 全局监控与验证
-
业务监控:观察消息堆积、消费延迟、连接数等指标。
-
集群同步状态 :检查镜像队列同步进度。
bashrabbitmqctl list_queues name messages_ready messages_unacknowledged
-
日志检查 :排查降配节点是否有异常报错。
bashtail -f /var/log/rabbitmq/rabbit@*.log
4. 降配后优化(可选)
- 调整内存阈值 :根据新配置优化 RabbitMQ 内存限制(
vm_memory_high_watermark
)。 - 磁盘空间监控:确保降配后的磁盘容量足够(RabbitMQ 默认需至少 50MB 剩余空间)。
风险点与应对
- 同步延迟:降配节点重启后,若队列数据量大,同步时间可能较长。建议在低峰期操作。
- 配置兼容性:确保新规格满足 RabbitMQ 最低要求(如内存不低于 1GB)。
- 网络波动:降配期间若节点 IP 变化,需更新集群节点列表和负载均衡配置。
总结
通过 逐节点滚动降配 + 负载均衡流量切换,可实现业务无感知。关键点在于确保镜像队列冗余、集群健康状态,以及操作顺序的严谨性。建议先在测试环境模拟流程,再在生产环境执行。
命令说明
查看集群状态命令 rabbitmqctl cluster_status
输出结果解析
bash
Cluster status of node rabbit@rabbitmq-prod-03 ...
[{nodes,[{disc,['rabbit@rabbitmq-prod-01','rabbit@rabbitmq-prod-02',
'rabbit@rabbitmq-prod-03']}]},
{running_nodes,['rabbit@rabbitmq-prod-02','rabbit@rabbitmq-prod-01',
'rabbit@rabbitmq-prod-03']},
{cluster_name,<<"rabbit@rabbitmq-prod-01">>},
{partitions,[]},
{alarms,[{'rabbit@rabbitmq-prod-02',[]},
{'rabbit@rabbitmq-prod-01',[]},
{'rabbit@rabbitmq-prod-03',[]}]}].
1. 集群节点状态
- 所有节点均在线 :
{nodes}
列表显示集群包含 3 个磁盘节点(disc
类型):rabbit@rabbitmq-prod-01
,rabbit@rabbitmq-prod-02
,rabbit@rabbitmq-prod-03
。{running_nodes}
列表显示这 3 个节点当前都在运行。
2. 网络分区
- 无网络分区 :
{partitions,[]}
表示没有发生网络分区问题。如果存在分区,partitions
字段会列出被隔离的节点及其分区信息。
3. 告警状态
- 无告警 :
{alarms,[{'rabbit@rabbitmq-prod-02',[]}, {'rabbit@rabbitmq-prod-01',[]}, {'rabbit@rabbitmq-prod-03',[]}]}
表明所有节点均未触发任何告警(如内存、磁盘空间不足等)。
4. 集群名称
- 集群名称一致 :
{cluster_name,<<"rabbit@rabbitmq-prod-01">>}
显示集群的名称为rabbit@rabbitmq-prod-01
,所有节点共享同一个集群名称,表明它们属于同一集群。
健康状态总结
从上述分析来看,你的 RabbitMQ 集群处于健康状态:
- 所有节点都在线且正常运行。
- 没有网络分区问题。
- 没有任何节点触发告警。
- 集群名称一致,结构完整。
进一步验证建议
虽然当前状态健康,但为了确保长期稳定运行,可以执行以下检查:
1. 检查队列镜像状态
确认队列是否在多个节点上正确镜像:
bash
rabbitmqctl list_queues name pid slave_pids synchronised_slave_pids
- 确保关键队列的
slave_pids
和synchronised_slave_pids
包含至少 2 个节点。
2. 检查资源使用情况
监控节点的 CPU、内存和磁盘使用率,避免因资源不足导致性能下降或告警:
bash
# 查看磁盘剩余空间
df -h
# 查看内存使用情况
free -m
# 查看 RabbitMQ 内存使用
rabbitmqctl status | grep -A 5 "memory"
3. 检查日志
查看 RabbitMQ 日志文件,排查潜在的警告或错误:
bash
tail -n 20 /var/log/rabbitmq/rabbit@*.log
4. 监控连接数
确保各节点的连接数在合理范围内:
bash
rabbitmqctl list_connections --node rabbit@rabbitmq-prod-03 | grep -v "Listing" | wc -l
查看节点同步状态 rabbitmqctl list_queues name pid slave_pids synchronised_slave_pids
命令输出解析
以下是 rabbitmqctl list_queues name pid slave_pids synchronised_slave_pids
的输出示例:
plaintext
name: collector_event
pid: <[email protected]>
slave_pids: [<[email protected]>, <[email protected]>]
synchronised_slave_pids: [<[email protected]>, <[email protected]>]
字段含义
-
name
:- 队列名称。例如:
collector_event
。
- 队列名称。例如:
-
pid
:- 主队列所在节点的进程 ID(Process ID)。例如:
<[email protected]>
表示主队列位于rabbit@rabbitmq-prod-03
节点。
- 主队列所在节点的进程 ID(Process ID)。例如:
-
slave_pids
:- 副本队列所在的节点和进程 ID 列表。例如:
<[email protected]>
表示该副本位于rabbit@rabbitmq-prod-02
。<[email protected]>
表示该副本位于rabbit@rabbitmq-prod-01
。
- 副本队列所在的节点和进程 ID 列表。例如:
-
synchronised_slave_pids
:- 已完成数据同步的副本队列所在的节点和进程 ID 列表。例如:
<[email protected]>
和<[email protected]>
表示这两个副本已完成同步。
- 已完成数据同步的副本队列所在的节点和进程 ID 列表。例如:
如何判断镜像同步完成
-
比较
slave_pids
和synchronised_slave_pids
:- 如果
synchronised_slave_pids
包含所有slave_pids
中的节点,则表示所有副本均已同步完成。 - 示例分析 :
slave_pids
:[<rabbit@rabbitmq-prod-02>, <rabbit@rabbitmq-prod-01>]
synchronised_slave_pids
:[<rabbit@rabbitmq-prod-01>, <rabbit@rabbitmq-prod-02>]
- 结论 :
synchronised_slave_pids
包含了所有slave_pids
,说明镜像已完全同步。
- 如果
-
检查数量是否一致:
- 如果
slave_pids
和synchronised_slave_pids
的数量相同,且内容一致,则镜像同步完成。
- 如果
-
异常情况:
- 如果
synchronised_slave_pids
为空或少于slave_pids
,则表示某些副本尚未完成同步,需等待同步完成后再继续操作。可以到管理界面queue界面查看有哪些队里没有同步完成,可点击进入队列并手动同步。
- 如果
删除队列
bash
rabbitmqctl delete_queue -p <host> <queue_name>
在 RabbitMQ 中执行删除队列(delete_queue
)操作时,如果出现 Access refused
错误,通常是由于权限问题导致的。以下是可能的原因及解决方法:
1. 用户权限不足
RabbitMQ 的用户权限分为三类:
- Configure:允许创建和删除队列、交换器等资源。
- Write:允许向队列发送消息。
- Read:允许从队列消费消息。
检查用户权限
使用以下命令查看当前用户的权限:
bash
rabbitmqctl list_permissions -p <vhost>
-
<vhost>
是目标虚拟主机,默认为/
。 -
输出示例:
Listing permissions for vhost "/" ... user configure write read guest .* .* .*
解决方法
确保当前用户对目标队列所在的虚拟主机具有足够的权限:
bash
# 授予用户对虚拟主机的权限
rabbitmqctl set_permissions -p <vhost> <username> ".*" ".*" ".*"
<username>
:当前登录 RabbitMQ 的用户名。"."*
:表示匹配所有资源。
2. 队列被其他消费者占用
如果队列正在被其他消费者使用(例如有活跃的连接或未确认的消息),删除操作可能会失败。
解决方法
-
停止消费者:确保没有客户端正在消费该队列。
-
清空队列 (可选):
bashrabbitmqadmin delete queue name=<queue_name>
或通过管理界面清空队列。
3. 用户未绑定到正确的虚拟主机
RabbitMQ 支持多虚拟主机(vhost
)。如果用户未绑定到目标队列所在的虚拟主机,也会导致权限拒绝。
检查虚拟主机
列出所有虚拟主机:
bash
rabbitmqctl list_vhosts
解决方法
将用户添加到正确的虚拟主机,并授予权限:
bash
# 添加用户到虚拟主机
rabbitmqctl add_user <username> <password>
rabbitmqctl set_permissions -p <vhost> <username> ".*" ".*" ".*"