RabbitMQ安裝
- RabbitMQ需要依賴erlang,如果普通安裝需要安裝erlang并保證二者兼容,因此選擇較為簡單的docker安裝方式
1.獲取rabbitmq鏡像
docker pull rabbitmq:3.11.19-management #rabbitmq-management表示帶有客戶端(控制臺)
docker pull rabbitmq:3.11.19 #如果只要服務端
2.啟動rabbitmq容器
docker run \
-d \
--name rabbitmq \
--hostname=rabbitmqNode1 \ #設置hostname,后續做集群時方便管理,這里將rabbitmq設為節點1
-v rabbitmq-plugins:/plugins \ #將rabbitmq的plugin目錄進行掛載,以便后續進行安裝rabbitmq插件
-v rabbitmq:/var/lib/rabbitmq \
-e RABBITMQ_DEFAULT_USER=admin \ #設置rabbitmq管理賬戶為admin、密碼為admin
-e RABBITMQ_DEFAULT_PASS=admin \
-e RABBITMQ_ERLANG_COOKIE='rabbitcookie' \ #集群部署時,Erlang Cookie 值必須都相同
-p 15672:15672 \ #15672是客戶端的端口,5672是服務端的端口
-p 5672:5672 \
--restart=always \
rabbitmq:3.11.19-management
3.開啟防火墻
firewall-cmd --zone=public --add-port=5672/tcp --permanent
firewall-cmd --zone=public --add-port=15672/tcp --permanent
firewall-cmd --reload
firewall-cmd --list-all # 查看已經開放的端口號
3.測試rabbitmq是否安裝完成
- 訪問
部署IP:15672
,觀察rabbitmq是否正常部署
RabbitMQ集群
- RabbitMQ集群部署時,必須保證Erlang Cookie相同
普通集群模式
-
目的:提高MQ的吞吐量
-
原理:普通集群模式下,broker之間復制元數據
- 生產者給一個broker發送消息,消費者連接的是另一個broker
- 生產者連接的broker會將消息轉發給消費者的broker,這樣就實現了分離消費端和生產端
-
普通集群模式進一步提高了MQ效率,但不保證高可用,如果一個節點宕機仍然會丟失消息
#如果要再加第三個節點就再--link
docker run -d --name rabbitmqCluster02 --hostname=node2 -v rabbitmqCluster02.plugins:/plugins -v rabbitmqCluster02:/var/lib/rabbitmq -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin -e RABBITMQ_ERLANG_COOKIE='rabbitcookie' -p 15673:15672 -p 5673:5672 --link rabbitmqCluster01:node1 rabbitmq:3.11.19-management
#節點2,進入容器,開啟集群
rabbitmqctl stop_apprabbitmqctl resetrabbitmqctl join_cluster rabbit@node1rabbitmqctl start_app#節點1,進入容器,重載配置
rabbitmqctl stop_apprabbitmqctl resetrabbitmqctl start_app
#這里加了一個--add-host,即將集群中其他的節點加入,這樣才能相互通信
#這里演示一主一從,創建node1節點時就將node2節點也加入,如果如果需要多個就增加幾個add-host參數即可
docker run \
-d \
--name rabbitmq \
-v rabbitmq-plugins:/plugins \
-v rabbitmq:/var/lib/rabbitmq \
--hostname=node1 \
--add-host=node2:192.168.1.43 \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=admin \
-e RABBITMQ_ERLANG_COOKIE='rabbitcookie' \
-p 4369:4369 \
-p 25672:25672 \
-p 15672:15672 \
-p 5672:5672 \
--restart=always \
rabbitmq:3.11.19-managementdocker run \
-d \
--name rabbitmq \
-v rabbitmq-plugins:/plugins \
-v rabbitmq:/var/lib/rabbitmq \
--hostname=node2 \
--add-host=node1:192.168.1.35 \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=admin \
-e RABBITMQ_ERLANG_COOKIE='rabbitcookie' \
-p 4369:4369 \
-p 25672:25672 \
-p 15672:15672 \
-p 5672:5672 \
--restart=always \
rabbitmq:3.11.19-management
鏡像隊列
-
目的:解決普通集群環境下高可用的問題
-
原理
- 隊列內容通過主從復制同步到多個節點,主節點處理讀寫請求,從節點實時同步數據
- 主節點故障時,從節點通過選舉機制自動接管,服務無感知切換
-
鏡像隊列雖然實現了高可用,但消息在節點間同步時出現宕機,仍有可能丟失消息
-
加入集群
# Node2/Node3執行 rabbitmqctl stop_app rabbitmqctl reset rabbitmqctl join_cluster --ram rabbit@rabbit1 # Node1為磁盤節點,其他可設為內存節點 rabbitmqctl start_app
-
驗證集群狀態
rabbitmqctl cluster_status # 輸出應包含所有節點,且running_nodes列表完整
-
創建鏡像策略
# 將所有隊列設置為鏡像隊列(全量同步) rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'# 或指定隊列前綴(如以"mirror_"開頭的隊列) rabbitmqctl set_policy ha-mirror "^mirror_" '{"ha-mode":"exactly","ha-params":2}'
仲裁隊列
-
目的:類似于redis的哨兵機制,進一步減小了消息丟失的風險
-
原理
- 多數派確認:消息需被超過半數節點(如3節點集群需2個確認)持久化后才返回成功響應,確保數據安全
- 選舉機制:若Leader宕機,Followers通過Raft協議發起選舉,新Leader需獲多數節點投票,避免腦裂
-
隊列聲明與配置
Map<String, Object> arguments = new HashMap<>();
arguments.put("x-queue-type", "quorum"); // 聲明為Quorum隊列
channel.queueDeclare("test-quorum-queue", true, false, false, arguments);
Streams隊列
-
目的:數據分片,進一步提高了傳輸性能
-
隊列聲明與配置
Map<String, Object> args = new HashMap<>();
args.put("x-queue-type", "stream"); // 必須設置為stream
args.put("x-max-length-bytes", 20_000_000_000L); // 最大20GB
args.put("x-stream-max-segment-size-bytes", 100_000_000); // 每段100MB
channel.queueDeclare("my-stream", true, false, false, args);