RabbitMQ 集群降配

这里写自定义目录标题

    • 摘要
    • 检查状态
      • [1. 检查 RabbitMQ 服务状态](#1. 检查 RabbitMQ 服务状态)
      • [2. 检查 RabbitMQ 端口监听](#2. 检查 RabbitMQ 端口监听)
      • [3. 检查 RabbitMQ 管理插件是否启用](#3. 检查 RabbitMQ 管理插件是否启用)
      • [4. 检查开机自启状态](#4. 检查开机自启状态)
      • [5. 确认集群高可用性](#5. 确认集群高可用性)
      • [6. 检查使用该集群的服务是否做了断开重连](#6. 检查使用该集群的服务是否做了断开重连)
    • 实操
      • [1. 负载均衡配置](#1. 负载均衡配置)
      • [2. 逐个节点降配(滚动操作)](#2. 逐个节点降配(滚动操作))
        • [2.1 停止 RabbitMQ 服务](#2.1 停止 RabbitMQ 服务)
        • [2.2 调整 ECS 配置](#2.2 调整 ECS 配置)
        • [2.3 恢复节点并重新加入集群](#2.3 恢复节点并重新加入集群)
        • [2.4 恢复负载均衡流量](#2.4 恢复负载均衡流量)
      • [3. 全局监控与验证](#3. 全局监控与验证)
      • [4. 降配后优化(可选)](#4. 降配后优化(可选))
      • 风险点与应对
      • 总结
    • 命令说明
      • [查看集群状态命令 rabbitmqctl cluster_status](#查看集群状态命令 rabbitmqctl cluster_status)
        • [1. 集群节点状态](#1. 集群节点状态)
        • [2. 网络分区](#2. 网络分区)
        • [3. 告警状态](#3. 告警状态)
        • [4. 集群名称](#4. 集群名称)
        • 健康状态总结
        • 进一步验证建议
          • [1. 检查队列镜像状态](#1. 检查队列镜像状态)
          • [2. 检查资源使用情况](#2. 检查资源使用情况)
          • [3. 检查日志](#3. 检查日志)
          • [4. 监控连接数](#4. 监控连接数)
      • [查看节点同步状态 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 错误,通常是由于权限问题导致的。以下是可能的原因及解决方法:)

摘要

背景 :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,且无网络分区问题。

    bash 复制代码
    rabbitmqctl cluster_status

6. 检查使用该集群的服务是否做了断开重连

实操

1. 负载均衡配置

  • 设置待降配节点的权重:在负载均衡(如 SLB)中暂时设置待操作节点的流量权重为0,确保降配期间流量仅路由到其他节点。

2. 逐个节点降配(滚动操作)

2.1 停止 RabbitMQ 服务
bash 复制代码
sudo systemctl stop rabbitmq-server
  • 验证节点离线 :检查集群状态,确认该节点已标记为 down

    bash 复制代码
    rabbitmqctl cluster_status
2.2 调整 ECS 配置
  • 关机 ECS
  • 降配操作:通过 ECS 控制台或 API 调整实例规格(CPU/内存)。
  • 重启 ECS(如需):若配置变更需要重启,确保重启后网络和存储正常挂载。
2.3 恢复节点并重新加入集群
  • 启动 RabbitMQ

    bash 复制代码
    sudo systemctl start rabbitmq-server
  • 重新加入集群 :如果节点因 IP 或主机名变化无法自动加入,需手动操作(一般不需要重新加入)

    bash 复制代码
    # 在新节点上重置 RabbitMQ 并重新加入集群
    rabbitmqctl stop_app
    rabbitmqctl reset
    rabbitmqctl join_cluster rabbit@<主节点主机名>
    rabbitmqctl start_app
  • 验证集群状态 :确保节点状态为 running,且队列镜像同步完成。

2.4 恢复负载均衡流量
  • 将节点权重恢复,观察健康检查状态。

3. 全局监控与验证

  • 业务监控:观察消息堆积、消费延迟、连接数等指标。

  • 集群同步状态 :检查镜像队列同步进度。

    bash 复制代码
    rabbitmqctl list_queues name messages_ready messages_unacknowledged
  • 日志检查 :排查降配节点是否有异常报错。

    bash 复制代码
    tail -f /var/log/rabbitmq/rabbit@*.log

4. 降配后优化(可选)

  • 调整内存阈值 :根据新配置优化 RabbitMQ 内存限制(vm_memory_high_watermark)。
  • 磁盘空间监控:确保降配后的磁盘容量足够(RabbitMQ 默认需至少 50MB 剩余空间)。

风险点与应对

  1. 同步延迟:降配节点重启后,若队列数据量大,同步时间可能较长。建议在低峰期操作。
  2. 配置兼容性:确保新规格满足 RabbitMQ 最低要求(如内存不低于 1GB)。
  3. 网络波动:降配期间若节点 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. 所有节点都在线且正常运行。
  2. 没有网络分区问题。
  3. 没有任何节点触发告警。
  4. 集群名称一致,结构完整。

进一步验证建议

虽然当前状态健康,但为了确保长期稳定运行,可以执行以下检查:

1. 检查队列镜像状态

确认队列是否在多个节点上正确镜像:

bash 复制代码
rabbitmqctl list_queues name pid slave_pids synchronised_slave_pids
  • 确保关键队列的 slave_pidssynchronised_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]>]
字段含义
  1. name

    • 队列名称。例如:collector_event
  2. pid

    • 主队列所在节点的进程 ID(Process ID)。例如:<[email protected]> 表示主队列位于 rabbit@rabbitmq-prod-03 节点。
  3. slave_pids

    • 副本队列所在的节点和进程 ID 列表。例如:
  4. synchronised_slave_pids


如何判断镜像同步完成
  1. 比较 slave_pidssynchronised_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,说明镜像已完全同步。
  2. 检查数量是否一致

    • 如果 slave_pidssynchronised_slave_pids 的数量相同,且内容一致,则镜像同步完成。
  3. 异常情况

    • 如果 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. 队列被其他消费者占用

如果队列正在被其他消费者使用(例如有活跃的连接或未确认的消息),删除操作可能会失败。

解决方法
  • 停止消费者:确保没有客户端正在消费该队列。

  • 清空队列 (可选):

    bash 复制代码
    rabbitmqadmin delete queue name=<queue_name>

    或通过管理界面清空队列。


3. 用户未绑定到正确的虚拟主机

RabbitMQ 支持多虚拟主机(vhost)。如果用户未绑定到目标队列所在的虚拟主机,也会导致权限拒绝。

检查虚拟主机

列出所有虚拟主机:

bash 复制代码
rabbitmqctl list_vhosts
解决方法

将用户添加到正确的虚拟主机,并授予权限:

bash 复制代码
# 添加用户到虚拟主机
rabbitmqctl add_user <username> <password>
rabbitmqctl set_permissions -p <vhost> <username> ".*" ".*" ".*"

相关推荐
快乐吃手手 : )6 小时前
RabbitMQ(补档)
分布式·rabbitmq
别说我什么都不会6 小时前
OpenHarmony源码分析之分布式软总线:authmanager模块(1)/设备认证连接管理
分布式·操作系统·harmonyos
青云交9 小时前
Java 大视界 -- 基于 Java 的大数据分布式存储系统的数据备份与恢复策略(139)
java·大数据·分布式·数据恢复·数据备份·分布式存储·并行处理
别说我什么都不会10 小时前
OpenHarmony源码分析之分布式软总线:os_adapter模块解析
分布式·harmonyos
nlog3n12 小时前
RabbitMQ八股文
分布式·rabbitmq
熏鱼的小迷弟Liu12 小时前
【RabbitMQ】RabbitMQ中死信交换机是什么?延迟队列呢?有哪些应用场景?
分布式·rabbitmq·ruby
熏鱼的小迷弟Liu12 小时前
【RabbitMQ】RabbitMQ如何保证消息不丢失?
分布式·rabbitmq
Gold Steps.13 小时前
Zookeeper 集群部署与管理实践
linux·分布式·zookeeper·云原生
初学者杰克13 小时前
记录一次,rabbitmq开启stomp插件之后,还是连不上15674端口的问题
分布式·rabbitmq