RabbitMQ系列(六)你不知道的RabbitMQ集羣架構全解

前言

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

知識點node

1、爲何使用集羣?正則表達式

2、集羣的特色docker

3、集羣異常處理json

4、集羣節點類型安全

5、集羣搭建方法bash

6、鏡像隊列服務器

1、爲何使用集羣?

內建集羣做爲RabbitMQ最優秀的功能之一,它的做用有兩個:cookie

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

2、集羣的特色

RabbitMQ的集羣是由多個節點組成的,但咱們發現不是每一個節點都有全部隊列的徹底拷貝。網絡

RabbitMQ節點不徹底拷貝特性

爲何默認狀況下RabbitMQ不將全部隊列內容和狀態複製到全部節點?

有兩個緣由:

  1. 存儲空間——若是每一個節點都擁有全部隊列的徹底拷貝,這樣新增節點不但沒有新增存儲空間,反而增長了更多的冗餘數據。
  2. 性能——若是消息的發佈需安全拷貝到每個集羣節點,那麼新增節點對網絡和磁盤負載都會有增長,這樣違背了創建集羣的初衷,新增節點並無提高處理消息的能力,最可能是保持和單節點相同的性能甚至是更糟。

因此其餘非全部者節點只知道隊列的元數據,和指向該隊列節點的指針。

3、集羣異常處理

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

這個問題要分爲兩種狀況:

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

4、集羣節點類型

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

  • 磁盤節點
  • 內存節點

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

單節點系統必須是磁盤節點,不然每次你重啓RabbitMQ以後全部的系統配置信息都會丟失。

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

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

若是集羣中的惟一一個磁盤節點,結果這個磁盤節點還崩潰了,那會發生什麼狀況?

若是惟一磁盤的磁盤節點崩潰了,不能進行以下操做:

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

總結:若是惟一磁盤的磁盤節點崩潰,集羣是能夠保持運行的,但你不能更改任何東西。

解決方案: 在集羣中設置兩個磁盤節點,只要一個能夠,你就能正常操做。

5、集羣搭建方法

本章咱們用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

集羣重啓順序

集羣重啓的順序是固定的,而且是相反的。 以下所述:

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

最後關閉必須是磁盤節點,否則可能回形成集羣啓動失敗、數據丟失等異常狀況。

6、鏡像隊列

鏡像隊列是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實戰-高效部署分佈式消息隊列》——不建議程序猿購買,偏運維 www.cnblogs.com/luo-mao/p/5… www.jianshu.com/p/85543491a…

長按二維碼,關注更多做者動態

相關文章
相關標籤/搜索