這里寫自定義目錄標題
- 摘要
- 檢查狀態
- 1. 檢查 RabbitMQ 服務狀態
- 2. 檢查 RabbitMQ 端口監聽
- 3. 檢查 RabbitMQ 管理插件是否啟用
- 4. 檢查開機自啟狀態
- 5. 確認集群高可用性
- 6. 檢查使用該集群的服務是否做了斷開重連
- 實操
- 1. 負載均衡配置
- 2. 逐個節點降配(滾動操作)
- 2.1 停止 RabbitMQ 服務
- 2.2 調整 ECS 配置
- 2.3 恢復節點并重新加入集群
- 2.4 恢復負載均衡流量
- 3. 全局監控與驗證
- 4. 降配后優化(可選)
- 風險點與應對
- 總結
- 命令說明
- 查看集群狀態命令 rabbitmqctl cluster_status
- 1. 集群節點狀態
- 2. 網絡分區
- 3. 告警狀態
- 4. 集群名稱
- 健康狀態總結
- 進一步驗證建議
- 1. 檢查隊列鏡像狀態
- 2. 檢查資源使用情況
- 3. 檢查日志
- 4. 監控連接數
- 查看節點同步狀態 rabbitmqctl list_queues name pid slave_pids synchronised_slave_pids
- 字段含義
- 如何判斷鏡像同步完成
- 刪除隊列
- 在 RabbitMQ 中執行刪除隊列(`delete_queue`)操作時,如果出現 `Access refused` 錯誤,通常是由于權限問題導致的。以下是可能的原因及解決方法:
- 1. 用戶權限不足
- 檢查用戶權限
- 解決方法
- 2. 隊列被其他消費者占用
- 解決方法
- 3. 用戶未綁定到正確的虛擬主機
- 檢查虛擬主機
- 解決方法
摘要
背景:2025年云成本優化仍是技術團隊的核心命題。當前需對遺留架構進行精細化治理,其中由前任架構師設計的RabbitMQ集群成為重點優化對象。該集群采用經典高可用架構,由3臺阿里云ECS實例構成核心節點,并通過負載均衡(SLB)實現流量分發。然而,經監控分析發現,節點資源利用率長期低于40%,存在顯著的配置冗余。在保障業務連續性的前提下,需通過降配調優實現成本節約。
ECS 配置:8C16G,CPU利用率 峰值18%, 內存峰值 25%
降配目標:平滑的將ECS節點降配至 2C8G
檢查狀態
1. 檢查 RabbitMQ 服務狀態
使用 systemctl
命令查看服務是否正在運行:
sudo systemctl status rabbitmq-server
- 輸出結果:
- 如果顯示
active (running)
,表示服務已啟動。 - 如果顯示
inactive (dead)
,表示服務未運行。
- 如果顯示
2. 檢查 RabbitMQ 端口監聽
RabbitMQ 默認監聽 5672
(AMQP 協議)和 15672
(管理界面)端口:
# 使用 netstat 或 ss 命令檢查端口
sudo netstat -tuln | grep -E '5672|15672'
# 或
sudo ss -tuln | grep -E '5672|15672'
- 輸出結果:如果有
LISTEN
狀態的端口,說明服務正常。
3. 檢查 RabbitMQ 管理插件是否啟用
若需通過 Web 界面管理 RabbitMQ,需確認管理插件是否啟用:
sudo rabbitmq-plugins list
- 輸出結果:查找
rabbitmq_management
是否標記為[E*]
(已啟用)。
4. 檢查開機自啟狀態
確認 RabbitMQ 是否設置為開機自啟:
sudo systemctl is-enabled rabbitmq-server
- 輸出結果:
enabled
:已設置開機自啟。disabled
:未設置開機自啟(可通過sudo systemctl enable rabbitmq-server
啟用)。
5. 確認集群高可用性
- 鏡像隊列配置:確保所有業務隊列已配置鏡像策略(如
ha-mode: all
或指定副本數),避免單節點故障導致消息丟失。# 查看當前策略 rabbitmqctl list_policies # 示例:設置所有隊列在3個節點鏡像 rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
- 集群狀態健康:確認所有節點狀態為
running
,且無網絡分區問題。rabbitmqctl cluster_status
6. 檢查使用該集群的服務是否做了斷開重連
實操
1. 負載均衡配置
- 設置待降配節點的權重:在負載均衡(如 SLB)中暫時設置待操作節點的流量權重為0,確保降配期間流量僅路由到其他節點。
2. 逐個節點降配(滾動操作)
2.1 停止 RabbitMQ 服務
sudo systemctl stop rabbitmq-server
- 驗證節點離線:檢查集群狀態,確認該節點已標記為
down
。rabbitmqctl cluster_status
2.2 調整 ECS 配置
- 關機 ECS
- 降配操作:通過 ECS 控制臺或 API 調整實例規格(CPU/內存)。
- 重啟 ECS(如需):若配置變更需要重啟,確保重啟后網絡和存儲正常掛載。
2.3 恢復節點并重新加入集群
- 啟動 RabbitMQ:
sudo systemctl start rabbitmq-server
- 重新加入集群:如果節點因 IP 或主機名變化無法自動加入,需手動操作(一般不需要重新加入)
# 在新節點上重置 RabbitMQ 并重新加入集群 rabbitmqctl stop_app rabbitmqctl reset rabbitmqctl join_cluster rabbit@<主節點主機名> rabbitmqctl start_app
- 驗證集群狀態:確保節點狀態為
running
,且隊列鏡像同步完成。
2.4 恢復負載均衡流量
- 將節點權重恢復,觀察健康檢查狀態。
3. 全局監控與驗證
- 業務監控:觀察消息堆積、消費延遲、連接數等指標。
- 集群同步狀態:檢查鏡像隊列同步進度。
rabbitmqctl list_queues name messages_ready messages_unacknowledged
- 日志檢查:排查降配節點是否有異常報錯。
tail -f /var/log/rabbitmq/rabbit@*.log
4. 降配后優化(可選)
- 調整內存閾值:根據新配置優化 RabbitMQ 內存限制(
vm_memory_high_watermark
)。 - 磁盤空間監控:確保降配后的磁盤容量足夠(RabbitMQ 默認需至少 50MB 剩余空間)。
風險點與應對
- 同步延遲:降配節點重啟后,若隊列數據量大,同步時間可能較長。建議在低峰期操作。
- 配置兼容性:確保新規格滿足 RabbitMQ 最低要求(如內存不低于 1GB)。
- 網絡波動:降配期間若節點 IP 變化,需更新集群節點列表和負載均衡配置。
總結
通過 逐節點滾動降配 + 負載均衡流量切換,可實現業務無感知。關鍵點在于確保鏡像隊列冗余、集群健康狀態,以及操作順序的嚴謹性。建議先在測試環境模擬流程,再在生產環境執行。
命令說明
查看集群狀態命令 rabbitmqctl cluster_status
輸出結果解析
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. 檢查隊列鏡像狀態
確認隊列是否在多個節點上正確鏡像:
rabbitmqctl list_queues name pid slave_pids synchronised_slave_pids
- 確保關鍵隊列的
slave_pids
和synchronised_slave_pids
包含至少 2 個節點。
2. 檢查資源使用情況
監控節點的 CPU、內存和磁盤使用率,避免因資源不足導致性能下降或告警:
# 查看磁盤剩余空間
df -h# 查看內存使用情況
free -m# 查看 RabbitMQ 內存使用
rabbitmqctl status | grep -A 5 "memory"
3. 檢查日志
查看 RabbitMQ 日志文件,排查潛在的警告或錯誤:
tail -n 20 /var/log/rabbitmq/rabbit@*.log
4. 監控連接數
確保各節點的連接數在合理范圍內:
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
的輸出示例:
name: collector_event
pid: <rabbit@rabbitmq-prod-03.1606707793.6080.60>
slave_pids: [<rabbit@rabbitmq-prod-02.1607654826.19286.68>, <rabbit@rabbitmq-prod-01.1606707802.17230.4475>]
synchronised_slave_pids: [<rabbit@rabbitmq-prod-01.1606707802.17230.4475>, <rabbit@rabbitmq-prod-02.1607654826.19286.68>]
字段含義
-
name
:- 隊列名稱。例如:
collector_event
。
- 隊列名稱。例如:
-
pid
:- 主隊列所在節點的進程 ID(Process ID)。例如:
<rabbit@rabbitmq-prod-03.1606707793.6080.60>
表示主隊列位于rabbit@rabbitmq-prod-03
節點。
- 主隊列所在節點的進程 ID(Process ID)。例如:
-
slave_pids
:- 副本隊列所在的節點和進程 ID 列表。例如:
<rabbit@rabbitmq-prod-02.1607654826.19286.68>
表示該副本位于rabbit@rabbitmq-prod-02
。<rabbit@rabbitmq-prod-01.1606707802.17230.4475>
表示該副本位于rabbit@rabbitmq-prod-01
。
- 副本隊列所在的節點和進程 ID 列表。例如:
-
synchronised_slave_pids
:- 已完成數據同步的副本隊列所在的節點和進程 ID 列表。例如:
<rabbit@rabbitmq-prod-01.1606707802.17230.4475>
和<rabbit@rabbitmq-prod-02.1607654826.19286.68>
表示這兩個副本已完成同步。
- 已完成數據同步的副本隊列所在的節點和進程 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界面查看有哪些隊里沒有同步完成,可點擊進入隊列并手動同步。
- 如果
刪除隊列
rabbitmqctl delete_queue -p <host> <queue_name>
在 RabbitMQ 中執行刪除隊列(delete_queue
)操作時,如果出現 Access refused
錯誤,通常是由于權限問題導致的。以下是可能的原因及解決方法:
1. 用戶權限不足
RabbitMQ 的用戶權限分為三類:
- Configure:允許創建和刪除隊列、交換器等資源。
- Write:允許向隊列發送消息。
- Read:允許從隊列消費消息。
檢查用戶權限
使用以下命令查看當前用戶的權限:
rabbitmqctl list_permissions -p <vhost>
<vhost>
是目標虛擬主機,默認為/
。- 輸出示例:
Listing permissions for vhost "/" ... user configure write read guest .* .* .*
解決方法
確保當前用戶對目標隊列所在的虛擬主機具有足夠的權限:
# 授予用戶對虛擬主機的權限
rabbitmqctl set_permissions -p <vhost> <username> ".*" ".*" ".*"
<username>
:當前登錄 RabbitMQ 的用戶名。"."*
:表示匹配所有資源。
2. 隊列被其他消費者占用
如果隊列正在被其他消費者使用(例如有活躍的連接或未確認的消息),刪除操作可能會失敗。
解決方法
- 停止消費者:確保沒有客戶端正在消費該隊列。
- 清空隊列(可選):
或通過管理界面清空隊列。rabbitmqadmin delete queue name=<queue_name>
3. 用戶未綁定到正確的虛擬主機
RabbitMQ 支持多虛擬主機(vhost
)。如果用戶未綁定到目標隊列所在的虛擬主機,也會導致權限拒絕。
檢查虛擬主機
列出所有虛擬主機:
rabbitmqctl list_vhosts
解決方法
將用戶添加到正確的虛擬主機,并授予權限:
# 添加用戶到虛擬主機
rabbitmqctl add_user <username> <password>
rabbitmqctl set_permissions -p <vhost> <username> ".*" ".*" ".*"