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

王磊的部落格發表於2018-07-25

前言

本文將系統的介紹一下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系列(六)你不知道的RabbitMQ叢集架構全解

到此為止,我們已經完成了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個節點的效果如下圖:

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

檢視映象佇列

rabbitmqctl list_policies

刪除映象佇列

rabbitmqctl clear_policy

參考資料

書籍:《RabbitMQ實戰-高效部署分散式訊息佇列》——不建議程式猿購買,偏運維 www.cnblogs.com/luo-mao/p/5… www.jianshu.com/p/85543491a…

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

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

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

相關文章