rabbitmq集羣是通過erlang的分佈式特性進行rabbitmq集羣,各個rabbitmq的服務爲相應的節點,每個節點都提供給客戶端連接,進行消息的發送與接收。
環境:CentOS 6.8 64位
服務器:192.168.179.128 wangwq01
192.168.179.129 wangwq02
192.168.179.130 wangwq03
1. 主機域名解析
rabbitmq各節點之間通信使用域名,所以集羣成員中所有主機名都要可解析,這裏使用修改hosts文件來實現解析。
2. 集羣的幾種實現方法及特性
1)手動使用rabbitmqctl創建
2)通過配置文件來列舉出集羣的節點
3)使用rabbitmq-autocluster來實現(此爲一個插件)
4)使用rabbitmq-cluster來實現(這也是個插件)
集羣可以動態構建與修改,即可以動態添加也可以動態脫離。集羣中的節點可以隨時關閉和啓動,也可以允許個別節點出現故障,只要在整個集羣中有正常節點即可。
節點可以是磁盤節點,也可以是內存節點,兩者之間可以互換使用,一般情況都是磁盤節點,特殊情況下使用內存節點可用於提高隊列、交換器或綁定的性能。
3. 設置cookie文件
rabbitmq集羣的節點間是使用cookie來確認通信的,所以集羣中的每個節點都必須有相同的erlang.cookie,同時保證文件權限是400且所屬用戶和組都一致
每個rabbitmq啓動時,erlang會自動創建一個cookie文件,爲了使每個節點的cookie保持一致,可以先讓其中一個節點來創建,然後將這個文件拷貝到其他節點的相應位置。默認cookie文件位於/var/lib/rabbitmq/.erlang.cookie
例:192.168.179.130創建了cookie文件,在192.168.179.129上
cd /var/lib/rabbitmq/
如果已經有了該文件,則刪除:
rm -rf .erlang.cookie scp [email protected]:/var/lib/rabbitmq/.erlang.cookie ./
查看文件所屬用戶和組以及權限是否滿足要求,不滿足則修改,否則會報錯:
Error when reading /var/lib/rabbitmq/.erlang.cookie: eacces
chown rabbitmq:rabbitmq .erlang.cookie chmod 400 .erlang.cookie
4. 啓動單個節點
運行命令:
rabbitmq-server -detached
可能會出錯:ERROR: node with name "rabbit" already running on "hostname"
這是因爲已經有一個運行的rabbitmq進程,停止即可:
ps aux|grep rabbitmq kill -15 PID
然後再次運行啓動命令。
這三個獨立的節點可以通過如下命令來驗證:
rabbitmqctl cluster_status
會看到:
Cluster status of node rabbit@rabbit01 ...
[{nodes,[{disc,[rabbit@rabbit01]}]},
{running_nodes,[rabbit@rabbit01]},
{cluster_name,<<"rabbit@localhost">>},
{partitions,[]},
{alarms,[{rabbit@rabbit01,[]}]}]
5. 創建集羣
要把單獨的節點構建到一個集羣中,可以暫定其中一個節點爲集羣中的第一個節點。然後依次將別的節點加入到集羣中(只要是已經成爲集羣中的節點,其他節點就可以通過該節點加入)。舉如下例子:
可以暫定rabbit@rabbit01爲集羣的第一個節點,先將rabbit@rabbit02加入到rabbit@rabbit01的集羣中,加入之前必須先停止rabbit02的rabbitmq應用程序,加入之後再啓動,然後rabbit@rabbit03可以通過rabbit@rabbit01加入,也可通過rabbit@rabbit02加入集羣。
在rabbit@rabbit02上:
rabbitmqctl stop_app rabbitmqctl join_cluster rabbit@rabbit01 rabbitmqctl start_app
加入過程中可能會遇到錯誤,如:Error: unable to connect to nodes [rabbit@rabbit01]: nodedown 這是因爲端口未開通導致無法連接到主機,可能是iptables沒有設置或者設置不當。
注:加入集羣時有兩種不同的節點類型:磁盤節點和內存節點。一個集羣中至少要有一個磁盤節點,當有節點加入或者離開時,必須要將變更通知到至少一個磁盤節點。如果集羣中只有一個磁盤節點或者只剩一個磁盤節點可用,這個磁盤節點崩潰之後,集羣扔可保持運行,但無法進行其他操作(增刪改查),直到節點恢復。所以集羣中最好設置兩個或以上的磁盤節點。
默認創建的爲磁盤節點,創建內存節點只需要加一個參數[--ram]:
rabbitmqctl join_cluster --ram rabbit@rabbit01
改變節點類型,如將內存節點更改爲磁盤節點:
rabbitmqctl stop_app rabbitmqctl change_cluster_node_type disc rabbitmqctl start_app
如果是開啓iptables的,添加如上端口的規則:
vi /etc/sysconfig/iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 4369 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 25672 -j ACCEPT :wq保存退出 /etc/init.d/iptables restart
這樣rabbit@rabbit02加加入到集羣中了,可以通過cluster_status命令查看:
rabbitmqctl cluster_status
如果正常 可看到:
Cluster status of node rabbit@rabbit02 ...
[{nodes,[{disc,[rabbit@rabbit01,rabbit@rabbit02]}]},
{running_nodes,[rabbit@rabbit01,rabbit@rabbit02]},
{cluster_name,<<"rabbit@localhost">>},
{partitions,[]},
{alarms,[{rabbit@rabbit01,[]},{rabbit@rabbit02,[]}]}]
在rabbit@rabbit01上也可查看到相同的信息。
然後將rabbit@rabbit03加入到集羣,這時它既可以選擇通過rabbit@rabbit01來加入,也可以選擇rabbit@rabbit02來加入,因爲01和02都是集羣的成員了。
在rabbit@rabbit03上:
rabbitmqctl stop_app rabbitmqctl join_cluster rabbit@rabbit02 rabbitmqctl start_app
在三個節點上分別使用cluster_status命令查看,可看到三個節點都在集羣裏了。
修改集羣的名字:
rabbitmqctl set_cluster_name new_mqname
6. 重啓集羣節點
加入到集羣中的節點,任何時候都允許停止,剩餘的節點不受影響繼續工作,重新啓動停止的節點會再次自動工作
如:停止rabbit@rabbit01
在rabbit01上:
rabbitmqctl stop
然後在集羣的某個節點中查看:
rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit02 ...
[{nodes,[{disc,[rabbit@rabbit01,rabbit@rabbit02,rabbit@rabbit03]}]},
{running_nodes,[rabbit@rabbit03,rabbit@rabbit02]},
{cluster_name,<<"rabbit@localhost">>},
{partitions,[]},
{alarms,[{rabbit@rabbit03,[]},{rabbit@rabbit02,[]}]}]
可看到運行的節點中少了rabbit@rabbit01,再次啓動rabbit01
rabbitmq-server -detached rabbitmqctl cluster_status
Cluster status of node rabbit@ rabbit01 ...
[{nodes,[{disc,[rabbit@ rabbit01,rabbit@ rabbit02,rabbit@ rabbit03]}]},
{running_nodes,[rabbit@ rabbit02,rabbit@ rabbit03,rabbit@ rabbit01]},
{cluster_name,<<"rabbit@localhost">>},
{partitions,[]},
{alarms,[{rabbit@ rabbit02,[]},{rabbit@ rabbit03,[]},{rabbit@ rabbit01,[]}]}]
注意:
1. 當整個集羣關閉時,最後一個關閉的節點必須要在下次第一個啓動,否則,節點會等待最後一個磁盤節點30s來確認重新連接,連接不到就會失敗。如果最後一個關閉的節點無法恢復,可以使用以下命令從集羣中刪除:
rabbitmqctl forget_cluster_node
2. 如果所有節點都在同一時間關閉(如斷電的情況),這會讓所有節點都認爲其他節點在自己之後,這種情況時,可以在其中的一個節點上執行以下命令使其成爲可啓動的:
rabbitmqctl force_boot
7. 脫離集羣
要刪除集羣中的節點,首先要停止rabbitmq應用程序,然後重設節點,完成之後再次啓動。刪除後的節點又會變爲獨立的節點。
例:將rabbit@rabbit03從節點中刪除
a. 在本節點刪除
在rabbit03上:
rabbitmqctl stop_app rabbitmqctl reset rabbitmqctl start_app
然後在節點上執行cluster_status命令來確認是否成功
在rabbit01上:
rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit01 ...
[{nodes,[{disc,[rabbit@rabbit01,rabbit@rabbit02]}]},
{running_nodes,[rabbit@rabbit02,rabbit@rabbit01]},
{cluster_name,<<"rabbit@localhost">>},
{partitions,[]},
{alarms,[{rabbit@rabbit02,[]},{rabbit@rabbit01,[]}]}]
在rabbit03上查看:
rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit03 ...
[{nodes,[{disc,[rabbit@rabbit03]}]},
{running_nodes,[rabbit@rabbit03]},
{cluster_name,<<"rabbit@rabbit03">>},
{partitions,[]},
{alarms,[{rabbit@rabbit03,[]}]}]
b. 遠程刪除
如在rabbit02上刪除rabbit03(依然要先停止應用程序)
在rabbit03上停止:
rabbitmqctl stop_app
在rabbit02上刪除:
rabbitmqctl forget_cluster_node rabbit@rabbit03
這時集羣中已經將rabbit03刪除了,但是rabbit03本身還不知道,依然認爲自己是集羣中的一員,所以啓動時會報錯:
Error description:
{error,{inconsistent_cluster,"Node rabbit@rabbit03 thinks it's clustered with node rabbit@rabbit02, but rabbit@rabbit02 disagrees"}}
想要讓rabbit03再次成爲單獨可使用的節點,需要進行重置。
在rabbit03上:
rabbitmqctl reset
然後再次啓動:
rabbitmqctl start_app