rabbit集羣

開始獨立節點
集羣是通過重新配置現有的RabbitMQ節點到集羣配置來設置。因此,第一步是在正常方式啓動RabbitMQ的所有節點:

rabbit1$ rabbitmq-server -detached
rabbit2$ rabbitmq-server -detached
rabbit3$ rabbitmq-server -detached

這將創建三個獨立的RabbitMQ中間件,一個在每個節點上,用來確認的cluster_status命令:

rabbit1$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit1 ...
[{nodes,[{disc,[rabbit@rabbit1]}]},{running_nodes,[rabbit@rabbit1]}]
...done.
rabbit2$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit2 ...
[{nodes,[{disc,[rabbit@rabbit2]}]},{running_nodes,[rabbit@rabbit2]}]
...done.
rabbit3$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit3 ...
[{nodes,[{disc,[rabbit@rabbit3]}]},{running_nodes,[rabbit@rabbit3]}]
...done.

RabbitMQ中間件的節點名稱從rabbitmq-server shell腳本開始,
rabbit@shorthostname ,這個短節點名稱是小寫(如:rabbit@rabbit1) 。如果你用rabbitmq-server.bat批處理文件,這個短節點名字是大寫(rabbit@RABBIT1) 。當你鍵入節點名稱時,重要情況,這些字符串必須匹配。

創建集羣
爲了在集羣中連接起來3個節點,我們告訴2個節點: rabbit@rabbit2 和 rabbit@rabbit3加入集羣的第三個, rabbit@rabbit1 。
我們首先連接 rabbit@rabbit2 和 rabbit@rabbit1 在集羣裏。爲了實現這個,我們停止rabbit@rabbit2 的RabbitMQ應用,加入rabbit@rabbit1 集羣,然後重啓RabbitMQ應用。
注意:加入一個集羣節點隱式重置,因此,移除了以前存在於該節點上的所有資源和數據。

rabbit2$ rabbitmqctl stop_app
Stopping node rabbit@rabbit2 ...done.
rabbit2$ rabbitmqctl join_cluster rabbit@rabbit1
Clustering node rabbit@rabbit2 with [rabbit@rabbit1] ...done.
rabbit2$ rabbitmqctl start_app
Starting node rabbit@rabbit2 ...done.

我們在任意一個節點上通過運行cluster_status命令看到2個節點加入到集羣了:

rabbit1$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit1 ...
[{nodes,[{disc,[rabbit@rabbit1,rabbit@rabbit2]}]},
 {running_nodes,[rabbit@rabbit2,rabbit@rabbit1]}]
...done.
rabbit2$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit2 ...
[{nodes,[{disc,[rabbit@rabbit1,rabbit@rabbit2]}]},
 {running_nodes,[rabbit@rabbit1,rabbit@rabbit2]}]
...done.

現在我們加入 rabbit@rabbit3 到同一個集羣。步驟與上面的步驟相同,只是這次我們集羣rabbit2來證明選擇的節點沒有集羣關係–它足以提供一個在線節點,並且該節點將集羣到指定節點所屬的集羣中。

rabbit3$ rabbitmqctl stop_app
Stopping node rabbit@rabbit3 ...done.
rabbit3$ rabbitmqctl join_cluster rabbit@rabbit2
Clustering node rabbit@rabbit3 with rabbit@rabbit2 ...done.
rabbit3$ rabbitmqctl start_app
Starting node rabbit@rabbit3 ...done.

我們在任意一個節點中通過運行cluster_status命令看到三個節點已經加入到集羣了:

rabbit1$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit1 ...
[{nodes,[{disc,[rabbit@rabbit1,rabbit@rabbit2,rabbit@rabbit3]}]},
 {running_nodes,[rabbit@rabbit3,rabbit@rabbit2,rabbit@rabbit1]}]
...done.
rabbit2$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit2 ...
[{nodes,[{disc,[rabbit@rabbit1,rabbit@rabbit2,rabbit@rabbit3]}]},
 {running_nodes,[rabbit@rabbit3,rabbit@rabbit1,rabbit@rabbit2]}]
...done.
rabbit3$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit3 ...
[{nodes,[{disc,[rabbit@rabbit3,rabbit@rabbit2,rabbit@rabbit1]}]},
 {running_nodes,[rabbit@rabbit2,rabbit@rabbit1,rabbit@rabbit3]}]
...done.

跟着以上步驟,我們可以隨時新增節點到集羣中,且集羣在運行的時候。

重啓集羣節點
已經加入到集羣的節點可以隨時停止。它們也可以奔潰。在這兩種情況下,集羣繼續運行不受影響,當它們再次啓動的時候,可以自動“追上”其他節點。
我們停止 rabbit@rabbit1 和 rabbit@rabbit3 節點,驗證集羣狀態的步驟:

rabbit1$ rabbitmqctl stop
Stopping and halting node rabbit@rabbit1 ...done.
rabbit2$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit2 ...
[{nodes,[{disc,[rabbit@rabbit1,rabbit@rabbit2,rabbit@rabbit3]}]},
 {running_nodes,[rabbit@rabbit3,rabbit@rabbit2]}]
...done.
rabbit3$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit3 ...
[{nodes,[{disc,[rabbit@rabbit1,rabbit@rabbit2,rabbit@rabbit3]}]},
 {running_nodes,[rabbit@rabbit2,rabbit@rabbit3]}]
...done.
rabbit3$ rabbitmqctl stop
Stopping and halting node rabbit@rabbit3 ...done.
rabbit2$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit2 ...
[{nodes,[{disc,[rabbit@rabbit1,rabbit@rabbit2,rabbit@rabbit3]}]},
 {running_nodes,[rabbit@rabbit2]}]
...done.

現在我們再次啓動節點,如我們進行的一樣來檢查集羣狀態:

rabbit1$ rabbitmq-server -detached
rabbit1$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit1 ...
[{nodes,[{disc,[rabbit@rabbit1,rabbit@rabbit2,rabbit@rabbit3]}]},
 {running_nodes,[rabbit@rabbit2,rabbit@rabbit1]}]
...done.
rabbit2$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit2 ...
[{nodes,[{disc,[rabbit@rabbit1,rabbit@rabbit2,rabbit@rabbit3]}]},
 {running_nodes,[rabbit@rabbit1,rabbit@rabbit2]}]
...done.
rabbit3$ rabbitmq-server -detached
rabbit1$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit1 ...
[{nodes,[{disc,[rabbit@rabbit1,rabbit@rabbit2,rabbit@rabbit3]}]},
 {running_nodes,[rabbit@rabbit2,rabbit@rabbit1,rabbit@rabbit3]}]
...done.
rabbit2$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit2 ...
[{nodes,[{disc,[rabbit@rabbit1,rabbit@rabbit2,rabbit@rabbit3]}]},
 {running_nodes,[rabbit@rabbit1,rabbit@rabbit2,rabbit@rabbit3]}]
...done.
rabbit3$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit3 ...
[{nodes,[{disc,[rabbit@rabbit1,rabbit@rabbit2,rabbit@rabbit3]}]},
 {running_nodes,[rabbit@rabbit2,rabbit@rabbit1,rabbit@rabbit3]}]
...done.

這裏有一些注意事項:
當整個集羣被刪除時,最後一個關閉的節點必須要在下次第一個啓動。如果不是這樣,這個節點將等待最後一個被關閉的節點啓動,這個等待時間是30秒,如果沒有等待,那麼這個先啓動的節點也會失敗。在新版本中會有重試機制,默認重試10次30秒以等待最後關閉的節點啓動。如果最後一個脫機的節點不能被備份,可以用forget_cluster_node命令從集羣中移除-諮詢rabbitmqctl幫助更多信息。

rabbit2$ rabbitmqctl forget_cluster_node rabbit@rabbit1 -offline

如果不添加“-offline”參數,就要保證rabbit2節點的RabbitMQ服務處於運行狀態,而在這種情況下,rabbit2無需先行啓動。”-offline”參數的添加可以讓其在非運行狀態下將rabbit1剝離出當前集羣。此功能也相當於剔除節點,和reset類似。

如果所有的節點都以同時或不受控制的方式停止(例如停電),則可以留下一個情況,即所有節點都認爲其它節點在它們之後停止。在這種情況下,你可以在一個節點上使用force_boot命令使它再次啓動。

打斷節點
當節點不再是集羣的一部分時,需要從其中顯式地移除。我們首先從集羣中移除rabbit@rabbit3,將其迴歸獨立運作。要做到這一點,我們需要停止在 rabbit@rabbit3上停止RabbitMQ應用,重置節點,並重啓RabbitMQ應用。

rabbit3$ rabbitmqctl stop_app
Stopping node rabbit@rabbit3 ...done.
rabbit3$ rabbitmqctl reset
Resetting node rabbit@rabbit3 ...done.
rabbit3$ rabbitmqctl start_app
Starting node rabbit@rabbit3 ...done.

注意,它會列出 rabbit@rabbit3 作爲一個節點同樣有效。
在節點上運行cluster_status命令,確認 rabbit@rabbit3 現在不再是集羣的一部分,並且操作獨立:

rabbit1$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit1 ...
[{nodes,[{disc,[rabbit@rabbit1,rabbit@rabbit2]}]},
 {running_nodes,[rabbit@rabbit2,rabbit@rabbit1]}]
...done.
rabbit2$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit2 ...
[{nodes,[{disc,[rabbit@rabbit1,rabbit@rabbit2]}]},
 {running_nodes,[rabbit@rabbit1,rabbit@rabbit2]}]
...done.
rabbit3$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit3 ...
[{nodes,[{disc,[rabbit@rabbit3]}]},{running_nodes,[rabbit@rabbit3]}]
...done.

我們也可以遠程刪除節點。這是有用的,例如,當必須處理一個沒有響應的節點。我們比如從 rabbit@rabbit2 移除 rabbit@rabbit1。

rabbit1$ rabbitmqctl stop_app
Stopping node rabbit@rabbit1 ...done.
rabbit2$ rabbitmqctl forget_cluster_node rabbit@rabbit1
Removing node rabbit@rabbit1 from cluster ...
...done.

注意:rabbit1仍然認爲它與rabbit2集羣,並且嘗試啓動,將會發生錯誤。我們需要重置它才能讓它重新啓動。

rabbit1$ rabbitmqctl start_app
Starting node rabbit@rabbit1 ...
Error: inconsistent_cluster: Node rabbit@rabbit1 thinks it's clustered with node rabbit@rabbit2, but rabbit@rabbit2 disagrees
rabbit1$ rabbitmqctl reset
Resetting node rabbit@rabbit1 ...done.
rabbit1$ rabbitmqctl start_app
Starting node rabbit@mcnulty ...
...done.

cluster_status命令現在顯示3個全部的節點都作爲獨立的RabbitMQ中間件操作。

rabbit1$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit1 ...
[{nodes,[{disc,[rabbit@rabbit1]}]},{running_nodes,[rabbit@rabbit1]}]
...done.
rabbit2$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit2 ...
[{nodes,[{disc,[rabbit@rabbit2]}]},{running_nodes,[rabbit@rabbit2]}]
...done.
rabbit3$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit3 ...
[{nodes,[{disc,[rabbit@rabbit3]}]},{running_nodes,[rabbit@rabbit3]}]
...done.

注意, rabbit@rabbit2 保留集羣殘餘狀態,而 rabbit@rabbit1 和 rabbit@rabbit3
初始化了RabbitMQ中間件,如果我們想重新初始化 rabbit@rabbit2 ,我們遵循其它
節點相同的步驟:

rabbit2$ rabbitmqctl stop_app
Stopping node rabbit@rabbit2 ...done.
rabbit2$ rabbitmqctl reset
Resetting node rabbit@rabbit2 ...done.
rabbit2$ rabbitmqctl start_app
Starting node rabbit@rabbit2 ...done.

升級集羣
當從一個大的或小的RabbitMQ版本升級爲另一個(如:3.0.x 到 3.1.x,或2.x.x 到 3.x.x),或者更新Erlang,整個集羣必須採取升級(因爲集羣不能像這樣運行混合的版本)。當從一個補丁版本升級到另一個補丁版本時(如3.0.x到3.0.y),通常不會出現這種情況,除非在發佈說明中另有說明;這些版本可以混在一個集羣中。因此,強烈建議在更新之前查閱發行說明。

一些補丁版本已知需要啓動的集羣範圍:
從3.0.x系列開始,3.0.0不能混合之後的版本
從3.6.x系列開始,3.6.6和之後的版本不能混合之前的版本。

當升級主要/次要版本時,必要時RabbitMQ會自動更新它的持久化數據結構。在集羣中,這個任務由要啓動的第一個磁盤節點執行(“更新”節點)。因此當RabbitMQ集羣升級,你不應該首先試圖啓動任何內存節點;啓動RAM節點將發出錯誤消息,無法啓動。

雖然沒有嚴格的必要,當節點將要升級時,決定提前停止最後一個節點,啓動第一個節點,這是一個好主意。否則改變集羣配置,停止升級的節點和停止最後一個節點將丟失。

自動升級只可能從RabbitMQ 2.1.1版本和之後的版本。如果你有一個較早的集羣,你需要重建它們升級。

單臺機器上的集羣
某些情況下,在一臺機器上運行RabbitMQ節點是很有用的。這通常是有用的,對於在桌面或筆記本電腦上沒有爲集羣啓動多個虛擬機的開銷的集羣實驗。
爲了運行多個RabbitMQ節點在一個單一的機器,確保節點有不同的節點名稱,數據存儲位置,日誌文件位置,和綁定不同的端口是必需的。詳情見RABBITMQ_NODENAME, RABBITMQ_NODE_PORT, and RABBITMQ_DIST_PORT。

你可以在同一個主機上通過rabbitmq-server重複調用來手動啓動多個節點(Windows上是rabbitmq-server.bat)。如:

$ RABBITMQ_NODE_PORT=5672 RABBITMQ_NODENAME=rabbit rabbitmq-server -detached
$ RABBITMQ_NODE_PORT=5673 RABBITMQ_NODENAME=hare rabbitmq-server -detached
$ rabbitmqctl -n hare stop_app
$ rabbitmqctl -n hare join_cluster rabbit@`hostname -s`
$ rabbitmqctl -n hare start_app

將設置2個節點,都是磁盤節點。注意:如果你的RabbitMQ開放了任何端口除了AMQP,你需要配置那些不衝突。這可以通過命令行來完成:

$ RABBITMQ_NODE_PORT=5672 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15672}]" RABBITMQ_NODENAME=rabbit rabbitmq-server -detached
$ RABBITMQ_NODE_PORT=5673 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15673}]" RABBITMQ_NODENAME=hare rabbitmq-server -detached

當管理插件安裝時,將啓動2個節點(然後可以集羣)。

主機名改變
RabbitMQ節點用主機名來互相交流。因此,所有節點名稱必須能夠解析所有的集羣節點的名稱。對於rabbitmqctl這樣的工具也是如此。
除此之外,默認情況下,RabbitMQ名稱數據庫目錄使用當前系統的主機名。如果主機名改變,一個新的空數據庫被創建。爲了避免數據丟失,建立一個固定的和可解析的主機名是至關重要的。
當主機名變化時,你應該重啓RabbitMQ:

$ /etc/init.d/rabbitmq-server restart

類似的效果,可以使用 rabbit@localhost 作爲中間件節點的名稱來實現。該解決方案的影響是,集羣將無法工作,因爲選擇的主機名不能解析遠程主機的路由地址。當從遠程主機調用時,rabbitmqctl命令同樣失敗。一個更復雜的不受這個弱點的解決方案是使用DNS,如:Amazon Route 53,如果運行在EC2。如果你想用完整的主機名作爲你的節點名(RabbitMQ默認的短名稱),使用DNS,完整的主機名是可以解析的,你可能需要研究設置環境變量RABBITMQ_USE_LONGNAME=true。

防火牆節點
當節點在數據中心或在一個可靠的網絡時,存在防火牆節點的情況,除了分離防火牆。同樣,不建議在廣域網或節點之間的網絡鏈路不可靠時進行集羣。
在最常見的配置中,您需要打開多個標準端口:
4369 (epmd)
5672, 5671 (AMQP 0-9-1 and 1.0 without and with TLS)
25672(這個端口被Erlang分佈用於節點間通信和命令行工具使用)
This port used by Erlang distribution for inter-node and CLI tools communication and is allocated from a dynamic range (limited to a single port by default, computed as AMQP port + 20000). See networking guide for details.
15672 (if management plugin is enabled)
61613, 61614 (if STOMP is enabled)
1883, 8883 (if MQTT is enabled)

從客戶端連接集羣
客戶機可以與集羣內的任何節點正常連接。如果該節點失敗,則其餘的羣集生存,然後客戶端應注意關閉連接,應該能夠重新連接到一些倖存的集羣成員。一般來說,不建議烤入節點主機名或IP地址到客戶端應用;本文介紹了剛性需要客戶端應用程序的編輯、編譯和部署該集羣變化或集羣中的節點數量的配置變化。相反,我們建議更抽象的方法:這可能是一個動態的DNS服務,有一個很短的TTL配置,或一個普通的TCP負載平衡器,或某種移動IP實現與起搏器或類似技術。總的來說,這方面的管理連接到集羣內的節點是超越RabbitMQ本身的範圍,我們建議使用其他專門設計來解決這些問題的技術。

帶內存節點的集羣
RabbitMQ中的每一個節點,不管是單一系統還是集羣,要麼是內存節點(RAM節點),要麼是磁盤節點。內存節點將所有的隊列、交換器、綁定關係、用戶、權限和vhost的元數據定義都存儲在內存中。單節點的集羣中必然只有磁盤類型節點,否則當重啓RabbitMQ之後,所有的系統配置信息都會丟失。由於RAM節點不必像磁盤節點對磁盤寫入一樣多,它們可以執行更好。然而,注意,由於持久隊列數據總是存儲在磁盤上,性能改進隻影響資源管理(如:增加或移除隊列,交換機或vhosts),但是沒有發佈或消耗速度。

內存節點是一個先進的用例;設置第一個羣集時,不應該使用它們。你應該有足夠的磁盤節點來處理你的冗餘需求,然後如果需要,添加額外的RAM節點的規模。

只包含RAM節點的羣集是脆弱的,如果羣集停止,您將無法重新啓動,將丟失所有數據。RabbitMQ將防止在許多情況下,創建只有RAM節點的集羣,但它不能完全阻止它。
RabbitMQ集羣中,如果只有一個磁盤節點,而且不湊巧剛好它崩潰了,那麼集羣可以繼續發送或接收消息,但是不能執行創建隊列、交換器、綁定關係、用戶,以及更改權限、添加或刪除集羣節點的操作了。也就是說直到該節點恢復前,你無法更改任何東西,所以在建立集羣時,應保證有兩個或多個磁盤節點存在。
創建內存節點
當它首次加入羣集時,我們可以聲明一個節點作爲RAM節點。我們如之前一樣用rabbitmqctl join_cluster 來做,但是傳遞–ram標誌:

rabbit2$ rabbitmqctl stop_app
Stopping node rabbit@rabbit2 ...done.
rabbit2$ rabbitmqctl join_cluster --ram rabbit@rabbit1
Clustering node rabbit@rabbit2 with [rabbit@rabbit1] ...done.
rabbit2$ rabbitmqctl start_app
Starting node rabbit@rabbit2 ...done.

RAM節點在羣集狀態中被顯示爲:

rabbit1$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit1 ...
[{nodes,[{disc,[rabbit@rabbit1]},{ram,[rabbit@rabbit2]}]},
 {running_nodes,[rabbit@rabbit2,rabbit@rabbit1]}]
...done.
rabbit2$ rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit2 ...
[{nodes,[{disc,[rabbit@rabbit1]},{ram,[rabbit@rabbit2]}]},
 {running_nodes,[rabbit@rabbit1,rabbit@rabbit2]}]
...done.

改變節點類型
我們可以改變從RAM到磁盤的節點類型,反之亦然。說我們想顛倒 rabbit@rabbit2和rabbit@rabbit1的類型,把前者從RAM節點變成磁盤節點,後者從磁盤節點變成RAM節點。我們可以使用change_cluster_node_type命令來做。節點首先必須被停止。

rabbit2$ rabbitmqctl stop_app
Stopping node rabbit@rabbit2 ...done.
rabbit2$ rabbitmqctl change_cluster_node_type disc
Turning rabbit@rabbit2 into a disc node ...
...done.
Starting node rabbit@rabbit2 ...done.
rabbit1$ rabbitmqctl stop_app
Stopping node rabbit@rabbit1 ...done.
rabbit1$ rabbitmqctl change_cluster_node_type ram
Turning rabbit@rabbit1 into a ram node ...
rabbit1$ rabbitmqctl start_app
Starting node rabbit@rabbit1 ...done.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章