rabbitmq高可用叢集的搭建
一.功能和原理
1.設計叢集的目的
(1)允許消費者和生產者在RabbitMQ節點崩潰的情況下繼續執行;
(2)通過增加更多的節點來擴充套件訊息通訊的吞吐量.
2.叢集配置方式
Rabbitmq可以通過三種方法來部署分散式集群系統,分別是:cluster,federation,shovel
a)cluster:
不支援跨網段,用於同一個網段內的區域網
可以隨意的動態增加或者減少
節點之間需要執行相同版本的Rabbitmq和Erlang
b)federation:
應用於廣域網,允許單臺伺服器上的交換機或者佇列接收發布到另外一臺伺服器上的交換機或佇列的訊息,可以是單臺機器或叢集.federation佇列類似於單向點對點連線,訊息會在聯盟佇列之間轉發任意次,直到被消費者接受.通常使用federation來連線internet上的中間伺服器,用作訂閱分發訊息或者工作佇列.
c)shovel:
連線方式與federation的連線方式類似,但它工作在更低層次,可以用於廣域網.
3.節點型別
叢集中的節點一般有兩種,一種是記憶體節點,一種是磁碟節點,記憶體節點由於沒有磁碟讀寫,效能比磁碟節點好,磁碟節點可以將狀態持久化到磁碟,可用性比記憶體節點好,需要權衡考慮.本次打算用一臺作為磁碟節點,做資料備份,兩臺記憶體節點,用於提高效能.
Rabbitmq要求在叢集中至少有一個磁碟節點,所有其他節點可以是記憶體節點,當節點加入或者離開叢集時,必須要將該變更通知到至少一個磁碟節點.如果叢集中唯一的磁碟節點崩潰的話,叢集仍然可以保持執行,但是無法進行其他的操作(增刪改查),直到節點恢復.
4.叢集模式
普通模式(預設):對於Queue來說,訊息實體只存在於其中的一個節點,A/B兩個節點僅有相同的元資料,即佇列結構.(交換機的所有元資料在所有節點上是一致的,而佇列的完整資訊只有在建立它的節點上,各個節點僅有相同的元資料,即佇列結構)當訊息進入A節點的Queue中後,consumer從B節點拉取資料時,RabbitMQ會臨時在A.B間進行訊息傳輸,把A中的訊息實體取出並經過B傳送給consumer.所以consumer應儘量連線每個節點,從中取訊息.即對於同一個邏輯佇列,要在多個節點建立物理Queue,否則無論consumer連A或B,出口總在A,會產生瓶頸.該模式存在一個問題就是當A節點故障後,B節點無法取到A節點中還未消費的訊息實體.如果做個訊息持久化,那麼等A幾點恢復,然後才可被消費;如果沒有做持久化,然後就...該模式非常適合非持久化佇列,只有該佇列是非持久化的,客戶端才能重新連線到叢集中的其他節點,並且重新建立佇列,如果該佇列是持久化的,那麼唯一的辦法就是將故障節點恢復起來.
映象模式(高可用模式):把需要的佇列做成映象模式,存在於多個節點,資料Rabbitmq的HA方案.該模式解決了上述問題,其實質和普通模式的不同之處在於,訊息實體會主動在映象節點間同步,而不會在consumer取資料時臨時拉取.該模式帶來的副作用也很明顯,除了降低系統性能意外,如果映象佇列過多,加之有大量的訊息進入,叢集內部的網路頻寬將會被這種同步通訊大大消耗掉,所以在對可靠性要求較高的場合中適用.
二.搭建步驟
1.配置hosts
在安裝好Rabbitmq的幾臺機器上,分別修改/etc/hosts檔案,必須修改為一樣的狀態. 例如:
172.17.0.1 rabbitmq1
172.17.0.2 rabbitmq2
172.17.0.3 rabbitmq3
2.配置cookie:
Erlang Cookie是保證不同節點可以互相通訊的祕鑰,要保證叢集中的不同節點互相通訊必須共享相同的Erlang Cookie,具體存放在/var/lib/rabbitmq/.erlang.cookie.說明:這就要從rabbitmqctl命令的工作原理說起,rabbitmq底層是通過Erlang架構來實現的,所以rabbitmqctl會啟動erlang節點,並基於Erlang節點來使用Erlang系統連線Rabbitmq節點,在連線過程中需要正確的Erlang和節點名稱,Erlang節點會通過交換Erlang Cookie以獲得認證.
Erlang節點間通過認證Erlang cookie的方式允許互相通訊.因為 rabbitmqctl 使用 Erlang OTP 通訊機制來和 Rabbit 節點通訊,允許rabbitmqctl 的機器和所要連線的Rabbit節點必須使用相同的Erlang cookie.否則,會報錯.檔案許可權要保持一致(400),各節點是通過這個cookie來進行通訊的.可以將其中一臺節點上.erlang.cookie值scp到其他節點上.具體做法如下:
(1)先備份原有cookie檔案,原節點啟停rabbitmq-service可以用到.
rabbit02# cp /var/lib/rabbitmq/.erlang.cookie /var/lib/rabbitmq/.erlang.cookie.bak
rabbit03# cp /var/lib/rabbitmq/.erlang.cookie /var/lib/rabbitmq/.erlang.cookie.bak
(2)修改cookie的值:
scp /var/lib/rabbitmq/.erlang.cookie 172.17.0.2:/var/lib/rabbitmq
scp /var/lib/rabbitmq/.erlang.cookie 172.17.0.3:/var/lib/rabbitmq
(3)在複製的時候需要臨時修改cookie檔案的許可權:
chmod 777 /var/lib/rabbitmq/.erlang.cookie
(4)拷貝完畢後再把許可權修改回來:
chmod 400 /var/lib/rabbitmq/.erlang.cookie
3.元件叢集
停掉所有節點上的rabbitmq服務,然後使用-detached獨立執行各個節點,這步很關鍵,尤其是增加節點停止節點後再次啟動遇到無法啟動時都可以參照這個順序進行.
rabbitmqctl stop
rabbitmq-server -detached
檢視叢集狀態:
rabbitmqctl cluster_status
此時都以單個節點的形式執行,{cluster_name,<<"[email protected]">>},這是叢集名字,其他節點可以 join 到這個叢集中。所有節點都是平等的,可以加入到任意一個叢集中,最終這些節點都會在同一個叢集中.
停掉其他rabbitmq節點,執行加入叢集的命令:
rabbitmqctl stop_app
rabbitmqctl join_cluster [email protected](注意:以記憶體節點的形式加入叢集的命令:
rabbitmqctl join_cluster --ram [email protected])
rabbitmqctl start_app
此時再次檢視叢集狀態,可以看到,各節點處於一個由rabbit01(disc node)、rabbit02(ram node)、rabbit03(ram node)組成的叢集
rabbitmqctl cluster_status
在管控臺介面也可以檢視到具體的叢集資訊.
注意:
(1)如果要將某個節點從叢集中移除,使其變回獨立節點,可以使用以下命令:
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
(2)如果需要啟停某個節點來進行維護,可以使用以下命令:
rabbitmqctl stop
rabbitmq-server -detached
(3)若要修改某個節點型別,可以使用以下命令:(使用之前先stop某個節點)
rabbitmqctl stop_app
rabbitmqctl change_cluster_node_type disc
(4)當新的節點加入到叢集之後,其使用者資訊也會被重置了(之前新增的admin賬戶不見了),需要重新配置管理員使用者,以便訪問到RabbitMQ管理介面(在任意節點新增使用者,會自動同步到各個節點).
新增管理員並授權:
rabbitmqctl add_user admin 123456
rabbitmqctl set_user_tags admin administrator
rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
rabbitmq-plugins enable rabbitmq_management(開啟web管理介面)
(5)退出叢集
假設把[email protected]退出叢集,在[email protected]上執行:
rabbitmqctl stop_app
在叢集主節點上執行:
rabbitmqctl forget_cluster_node [email protected]
4.設定映象佇列策略:
在任意一個節點上執行:
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
即所有的佇列設定為映象佇列,即佇列會被複制到各個節點,各個節點狀態保持一致.完成以上步驟以後,Rabbitmq高可用叢集就已經搭建好了,最後一個步驟是是搭建負載均衡器.
補充說明:abbitmqctl set_policy -p hrsystem ha-allqueue "^" '{"ha-mode":"all"}'
這一行命令是在vhost名稱為hrsystem建立一個策略,策略名稱為ha-allqueue,策略模式為all,即複製到所有節點,包含新增節點,策略表示式為"^",表示所有匹配所有佇列名稱.
檢視策略:rabbitmqctl list_policies -p /
清除策略:rabbitmqctl clear_policy -p / ha-allweb3.0
5.RabbitMQ負載均衡配置---選擇開源的HAProxy為RabbitMQ叢集做負載均衡器
搭建過程可參考:http://blog.51cto.com/freeloda/1294094
關於配置檔案/etc/haproxy/haproxy.cfg的簡單說明:
server node1 192.168.1.1:5672 check inter 2000 rise 2 fall 3 //負載均衡中的節點配置,這裡選擇rabbit節點.
server node2 192.168.1.2:5672 check inter 2000 rise 2 fall 3
#server node2 192.168.1.3:5672 check inter 2000 rise 2 fall 3
負載均衡器會監聽5672埠,輪詢兩個記憶體節點192.168.1.1和192.168.1.2的5672埠,第三臺為磁碟節點,只做備份,不提供給生產者和消費者使用,當然伺服器資源充足的情況下也可配置多個磁碟節點,這樣磁碟節點出了故障也不會影響.
文末
1.關於叢集恢復與故障轉移:
從節點停機解決:在主節點執行rabbitmqctl forget_cluster_node slavenode ,然後再把從節點加入叢集.
主節點停機恢復:rabbitmqctl forget_cluster_node --offline slavenode執行該命令,支援線下恢復.等主節點恢復,再把從節點加入進去.
2.重要檔案儲存位置:
-
/usr/local/rabbitmq_server/var/log/rabbitmq/[email protected]:rabbitmq的崩潰報告
-
/usr/local/rabbitmq_server/etc/rabbitmq/rabbitmq.config:rabbitmq的配置檔案
-
/usr/local/rabbitmq_server/var/lib/rabbitmq/mnesia/[email protected]:rabbit訊息持久化檔案
-
/usr/local/rabbitmq_server/var/log/rabbitmq/[email protected]:記錄rabbitmq執行日常的日誌
3.參考連結:
https://blog.csdn.net/qq_22075041/article/details/78855708
https://88250.b3log.org/rabbitmq-clustering-ha
https://blog.csdn.net/qq_35246620/article/details/72473098
https://my.oschina.net/jiaoyanli/blog/822011
http://www.imooc.com/article/46311
http://chyufly.github.io/blog/2016/04/10/rabbitmq-cluster/
https://www.jianshu.com/p/97fbf9c82872
https://cloud.tencent.com/developer/article/1014974
http://blog.51cto.com/ghbsunny/2154269
http://www.voidcn.com/article/p-vlhrergj-bsb.html
https://mshk.top/2016/08/rabbitmq-haproxy/
http://www.rabbitmq.com/rabbitmqctl.8.html
http://www.rabbitmq.com/ha.html