1. 程式人生 > >你不知道的RabbitMQ集群架構全解

你不知道的RabbitMQ集群架構全解

fanout 保持 mqc json字符串 完成 就是 原因 正則表達 每一個

你不知道的RabbitMQ集群架構全解

RabbitMQ系列文章

  1. RabbitMQ在Ubuntu上的環境搭建
  2. 深入了解RabbitMQ工作原理及簡單使用
  3. RabbitMQ交換器Exchange介紹與實踐
  4. RabbitMQ事務和Confirm發送方消息確認——深入解讀
  5. 使用Docker部署RabbitMQ集群
  6. 你不知道的RabbitMQ集群架構全解

前言

本文將系統的介紹一下RabbitMQ集群架構的特點、異常處理、搭建和使用中要註意的一些細節。

知識點

一、為什麽使用集群?

二、集群的特點

三、集群異常處理

四、集群節點類型

五、集群搭建方法

六、鏡像隊列

一、為什麽使用集群?

內建集群作為RabbitMQ最優秀的功能之一,它的作用有兩個:

  1. 允許消費者和生產者在Rabbit節點崩潰的情況下繼續運行;
  2. 通過增加節點來擴展Rabbit處理更多的消息,承載更多的業務量;

二、集群的特點

RabbitMQ的集群是由多個節點組成的,但我們發現不是每個節點都有所有隊列的完全拷貝。

RabbitMQ節點不完全拷貝特性

為什麽默認情況下RabbitMQ不將所有隊列內容和狀態復制到所有節點?

有兩個原因:

  1. 存儲空間——如果每個節點都擁有所有隊列的完全拷貝,這樣新增節點不但沒有新增存儲空間,反而增加了更多的冗余數據。
  2. 性能——如果消息的發布需安全拷貝到每一個集群節點,那麽新增節點對網絡和磁盤負載都會有增加,這樣違背了建立集群的初衷,新增節點並沒有提升處理消息的能力,最多是保持和單節點相同的性能甚至是更糟。

所以其他非所有者節點只知道隊列的元數據,和指向該隊列節點的指針。

三、集群異常處理

根據節點不無安全拷貝的特性,當集群節點崩潰時,該節點隊列和關聯的綁定就都丟失了,附加在該隊列的消費者丟失了其訂閱的信息,那麽怎麽處理這個問題呢?

這個問題要分為兩種情況:

  1. 消息已經進行了持久化,那麽當節點恢復,消息也恢復了;
  2. 消息未持久化,可以使用下文要介紹的雙活冗余隊列,鏡像隊列保證消息的可靠性;

四、集群節點類型

節點的存儲類型分為兩種:

  • 磁盤節點
  • 內存節點

磁盤節點就是配置信息和元信息存儲在磁盤上,內次節點把這些信息存儲在內存中,當然內次節點的性能是大大超越磁盤節點的。

單節點系統必須是磁盤節點

,否則每次你重啟RabbitMQ之後所有的系統配置信息都會丟失。

RabbitMQ要求集群中至少有一個磁盤節點,當節點加入和離開集群時,必須通知磁盤節點。

特殊異常:集群中唯一的磁盤節點崩潰了

如果集群中的唯一一個磁盤節點,結果這個磁盤節點還崩潰了,那會發生什麽情況?

如果唯一磁盤的磁盤節點崩潰了,不能進行如下操作:

  • 不能創建隊列
  • 不能創建交換器
  • 不能創建綁定
  • 不能添加用戶
  • 不能更改權限
  • 不能添加和刪除集群幾點

總結:如果唯一磁盤的磁盤節點崩潰,集群是可以保持運行的,但你不能更改任何東西。

解決方案:在集群中設置兩個磁盤節點,只要一個可以,你就能正常操作。

五、集群搭建方法

本章我們用Docker來創建RabbitMQ集群,一來是因為操作簡便,二是因為可以更充分的利用服務器硬件資源,三來是Docker也是現在的主流部署方案,關於更多的Docker詳情可以查看我的另一篇:《使用Docker部署RabbitMQ集群)》 接下來,進入我們的正文,集群搭建分為兩步:

  • 步驟一:安裝多個RabbitMQ
  • 步驟二:加入RabbitMQ節點到集群

步驟一:安裝多個RabbitMQ

docker run -d --hostname rabbit1 --name myrabbit1 -p 15672:15672 -p 5672:5672 -e RABBITMQ_ERLANG_COOKIE='rabbitcookie' rabbitmq:3.6.15-management

docker run -d --hostname rabbit2 --name myrabbit2 -p 5673:5672 --link myrabbit1:rabbit1 -e RABBITMQ_ERLANG_COOKIE='rabbitcookie' rabbitmq:3.6.15-management

docker run -d --hostname rabbit3 --name myrabbit3 -p 5674:5672 --link myrabbit1:rabbit1 --link myrabbit2:rabbit2 -e RABBITMQ_ERLANG_COOKIE='rabbitcookie' rabbitmq:3.6.15-management

具體的參數含義,參見上文“啟動RabbitMQ”部分。

註意點:

  1. 多個容器之間使用“--link”連接,此屬性不能少;
  2. Erlang Cookie值必須相同,也就是RABBITMQ_ERLANG_COOKIE參數的值必須相同,原因見下文“配置相同Erlang Cookie”部分;

步驟二:加入RabbitMQ節點到集群

設置節點1:

docker exec -it myrabbit1 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
exit

設置節點2,加入到集群:

docker exec -it myrabbit2 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbit1
rabbitmqctl start_app
exit

參數“--ram”表示設置為內存節點,忽略次參數默認為磁盤節點。

設置節點3,加入到集群:

docker exec -it myrabbit3 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbit1
rabbitmqctl start_app
exit

設置好之後,使用http://物理機ip:15672 進行訪問了,默認賬號密碼是guest/guest,效果如下圖:

技術分享圖片

到此為止,我們已經完成了RabbitMQ集群的建立,啟動了3個節點,1個磁盤節點和2個內存節點。

設置節點類型

如果你想更換節點類型可以通過命令修改,如下:

rabbitmqctl stop_app

rabbitmqctl change_cluster_node_type dist

rabbitmqctl change_cluster_node_type ram

rabbitmqctl start_app

移除節點

如果想要把節點從集群中移除,可使用如下命令實現:

rabbitmqctl stop_app

rabbitmqctl restart

rabbitmqctl start_app

集群重啟順序

集群重啟的順序是固定的,並且是相反的。如下所述:

  • 啟動順序:磁盤節點 => 內存節點
  • 關閉順序:內存節點 => 磁盤節點

最後關閉必須是磁盤節點,不然可能回造成集群啟動失敗、數據丟失等異常情況。

六、鏡像隊列

鏡像隊列是Rabbit2.6.0版本帶來的一個新功能,允許內建雙活冗余選項,與普通隊列不同,鏡像節點在集群中的其他節點擁有從隊列拷貝,一旦主節點不可用,最老的從隊列將被選舉為新的主隊列。

鏡像隊列的工作原理:在某種程度上你可以將鏡像隊列視為,擁有一個隱藏的fanout交換器,它指示者信道將消息分發到從隊列上。

設置鏡像隊列

設置鏡像隊列命令:“rabbitmqctl set_policy 名稱 匹配模式(正則) 鏡像定義”, 例如,設置名稱為mypolicy的鏡像隊列,匹配所有名稱是amp開頭的隊列都存儲在2個節點上的命令如下:

rabbitmqctl set_policy mypolicy "^amp*" ‘{"ha-mode":"exactly","ha-params":2}‘

可以看出設置鏡像隊列,一共有三個參數,每個參數用空格分割

  1. 參數一:名稱,可以隨便填;
  2. 參數二:隊列名稱的匹配規則,使用正則表達式表示;
  3. 參數三:為鏡像隊列的主體規則,是json字符串,分為三個屬性:ha-mode | ha-params | ha-sync-mode,分別的解釋如下:
  • ha-mode:鏡像模式,分類:all/exactly/nodes,all存儲在所有節點;exactly存儲x個節點,節點的個數由ha-params指定;nodes指定存儲的節點上名稱,通過ha-params指定;
  • ha-params:作為參數,為ha-mode的補充;
  • ha-sync-mode:鏡像消息同步方式:automatic(自動),manually(手動);

設置好鏡像隊列存儲2個節點的效果如下圖:

技術分享圖片

查看鏡像隊列

rabbitmqctl list_policies

刪除鏡像隊列

rabbitmqctl clear_policy

參考資料

書籍:《RabbitMQ實戰-高效部署分布式消息隊列》——不建議程序猿購買,偏運維
https://www.cnblogs.com/luo-mao/p/5909889.html
https://www.jianshu.com/p/85543491ab00

長按二維碼,關註更多作者動態
技術分享圖片

你不知道的RabbitMQ集群架構全解