RabbitMQ兩種叢集模式配置管理
一、RabbitMQ叢集的兩種模式
1)普通模式:預設的叢集模式。
2)映象模式:把需要的佇列做成映象佇列,存在於多個節點,屬於RabbitMQ的HA方案
普通模式:預設的叢集模式
RabbitMQ叢集中節點包括記憶體節點、磁碟節點。記憶體節點就是將所有資料放在記憶體,磁碟節點將資料放在磁碟上。如果在投遞訊息時,打開了訊息的持久化,那麼即使是記憶體節點,資料還是安全的放在磁碟。那麼記憶體節點的效能只能體現在資源管理上,比如增加或刪除佇列(queue),虛擬主機(vrtual hosts),交換機(exchange)等,傳送和接受message速度同磁碟節點一樣。一個叢集至少要有一個磁碟節點。一個rabbitmq叢集中可以共享user,vhost,exchange等,所有的資料和狀態都是必須在所有節點上覆制的,對於queue根據叢集模式不同,應該有不同的表現。在叢集模式下只要有任何一個節點能夠工作,RabbitMQ叢集對外就能提供服務。
預設的叢集模式,queue建立之後,如果沒有其它policy,則queue就會按照普通模式叢集。對於Queue來說,訊息實體只存在於其中一個節點,A、B兩個節點僅有相同的元資料,即佇列結構,但佇列的元資料僅儲存有一份,即建立該佇列的rabbitmq節點(A節點),當A節點宕機,你可以去其B節點檢視,./rabbitmqctl list_queues發現該佇列已經丟失,但宣告的exchange還存在。
當訊息進入A節點的Queue中後,consumer從B節點拉取時,RabbitMQ會臨時在A、B間進行訊息傳輸,把A中的訊息實體取出並經過B傳送給consumer,所以consumer應平均連線每一個節點,從中取訊息。該模式存在一個問題就是當A節點故障後,B節點無法取到A節點中還未消費的訊息實體。如果做了佇列持久化或訊息持久化,那麼得等A節點恢復,然後才可被消費,並且在A節點恢復之前其它節點不能再建立A節點已經建立過的持久佇列;如果沒有持久化的話,訊息就會失丟。這種模式更適合非持久化佇列,只有該佇列是非持久的,客戶端才能重新連線到叢集裡的其他節點,並重新建立佇列。假如該佇列是持久化的,那麼唯一辦法是將故障節點恢復起來。
為什麼RabbitMQ不將佇列複製到叢集裡每個節點呢?這與它的叢集的設計本意相沖突,叢集的設計目的就是增加更多節點時,能線性的增加效能(CPU、記憶體)和容量(記憶體、磁碟)。當然RabbitMQ新版本叢集也支援佇列複製(有個選項可以配置)。比如在有五個節點的叢集裡,可以指定某個佇列的內容在2個節點上進行儲存,從而在效能與高可用性之間取得一個平衡(應該就是指映象模式)。
映象模式:把需要的佇列做成映象佇列,存在於多個節點,屬於RabbitMQ的HA方案
該模式解決了上述問題,其實質和普通模式不同之處在於,訊息實體會主動在映象節點間同步,而不是在consumer取資料時臨時拉取。該模式帶來的副作用也很明顯,除了降低系統性能外,如果映象佇列數量過多,加之大量的訊息進入,叢集內部的網路頻寬將會被這種同步通訊大大消耗掉。所以在對可靠性要求較高的場合中適用,一個佇列想做成映象佇列,需要先設定policy,然後客戶端建立佇列的時候,rabbitmq叢集根據“佇列名稱”自動設定是普通叢集模式或映象佇列。
二、RabbitMQ普通叢集配置
1、每臺主機均安裝 rabbitmq
環境:
主機名 :ip
mq-161 : 10.100.0.161
mq-162 : 10.100.0.162
mq-163 : 10.100.0.163
ubuntu系統
install rabbitmq-server # 直接搞定
以下centos系統
1)Install Erlang
# For EL5:
rpm -Uvh http://download.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm
# For EL6:
rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
# For EL7:
rpm -Uvh http://download.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-8.noarch.rpm
yum install erlang
2)Install RabbitMQ Server
rpm --import https://www.rabbitmq.com/rabbitmq-release-signing-key.asc
yum install rabbitmq-server-3.6.5-1.noarch.rpm
3)use RabbitMQ Server
chkconfig rabbitmq-server on
service rabbitmq-server stop/start
2、RabbitMQ叢集搭建
1)RabbitMQ叢集搭建
均同步主機的/etc/hosts檔案
10.100.0.161 mq-161
10.100.0.162 mq-162
10.100.0.163 mq-163
同步erlang.cookie檔案,叢集主機統一,通過Erlang的分散式特性(通過magic cookie認證節點)進行RabbitMQ叢集,各RabbitMQ服務為對等節點,即每個節點都提供服務給客戶端連線,進行訊息傳送與接收。
root@mq-161:~ # cat /var/lib/rabbitmq/.erlang.cookie
WJLPTHZIMFLJRTOGPYNA
root@mq-162:~ # cat /var/lib/rabbitmq/.erlang.cookie
WJLPTHZIMFLJRTOGPYNA
root@mq-163:~ # cat /var/lib/rabbitmq/.erlang.cookie
WJLPTHZIMFLJRTOGPYNA
編譯安裝,普通使用者啟動的話,.erlang.cookie檔案會在宿主目錄下生成
在mq-161節點上檢視叢集資訊,此時叢集中應只有自己。
[email protected]161:~ # rabbitmqctl cluster_status
Cluster status of node '[email protected]' ...
[
{nodes,[{disc,['[email protected]']}]},
#叢集中的節點,disc表示為磁碟模式,ram表示為記憶體模式
{running_nodes,['[email protected]']},
#正在執行的叢集節點
{cluster_name,<<"[email protected]">>},
#叢集的名稱
{partitions,[]}
]
...done.
下面將mq-161、mq-162、mq-163組成叢集:
mq-162加入mq-161節點。
root@mq-162:~ # rabbitmqctl stop_app
root@mq-162:~ # rabbitmqctl join_cluster rabbit@mq-161
root@mq-162:~ # rabbitmqctl start_app
mq-163加入mq-161節點。
root@mq-163:~ # rabbitmqctl stop_app
root@mq-163:~ # rabbitmqctl join_cluster rabbit@mq-161 --ram
root@mq-163:~ # rabbitmqctl start_app
此時mq-162與mq-163也會自動建立連線,上面我的兩個節點,其中mq-162是磁碟節點,mq-163是記憶體節點,但mq-161節點預設是磁碟節點(一個叢集中最少要有一個磁碟節點)。如果想把mq-162由磁碟節點改成記憶體節點,使用如下change_cluster_node_type命令修改即可,但要先stop:
[email protected]162:~ # rabbitmqctl stop_app
Stopping node '[email protected]' ...
...done.
[email protected]162:~ # rabbitmqctl change_cluster_node_type ram
Turning '[email protected]' into a ram node ...
...done.
[email protected]162:~ # rabbitmqctl start_app
Starting node '[email protected]' ...
...done.
2)允許遠端使用者訪問
# 第一、新增mq使用者並設定密碼
rabbitmqctl add_user mq 123456
# 第二、設定mq使用者為管理員
rabbitmqctl set_user_tags mq administrator
# 第三、設定mq使用者的許可權,指定允許訪問的vhost以及write/read
rabbitmqctl set_permissions -p "/" mq ".*" ".*" ".*"
Setting permissions for user "live" in vhost "/" ...
...done.
# 第四、檢視vhost(/)允許哪些使用者訪問
rabbitmqctl list_permissions -p /
Listing permissions in vhost "/" ...
mq .* .* .*
...done.
# 第五、配置允許遠端訪問的使用者,rabbitmq的guest使用者預設不允許遠端主機訪問。
cat /etc/rabbitmq/rabbitmq.config
[
{rabbit, [{tcp_listeners, [5672]}, {loopback_users, ["mq"]}]}
].
# ps:主機1設定完以上這些之後,在叢集內的機器都會同步此配置,但是/etc/rabbitmq/rabbitmq.config檔案不會同步。
rabbitmqctl list_users
Listing users ...
mq [administrator]
...done.
最後,可以選擇刪除預設guest使用者(密碼也是guest)
rabbitmqctl delete_user guest
三、RabbitMQ映象叢集配置
上述配置的RabbitMQ預設叢集模式,但並不包管佇列的高可用性,儘管互換機、繫結這些可以複製到叢集裡的任何一個節點,然則佇列內容不會複製。固然該模式解決一專案組節點壓力,但佇列節點宕機直接導致該佇列無法應用,只能守候重啟,所以要想在佇列節點宕機或故障也能正常應用,就要複製佇列內容到叢集裡的每個節點,須要建立映象佇列。
映象佇列是基於普通的叢集模式的,所以你還是得先配置普通叢集,然後才能設定映象佇列,我們就以上面的叢集接著做。
我是通過上面開啟的網頁的管理端來設定的映象佇列,也可以通過命令,這裡先說其中的網頁設定方式:
1、點選admin選單–>右側的Policies選項–>左側最下下邊的Add/update a policy。
2、按照圖中的內容根據自己的需求填寫。
3、點選Add policy新增策略。
此時你就會來你的兩臺rabbitmq伺服器的網頁管理端amind選單下看見剛才建立的隊列了,下面我們來新增一個queues佇列來看看效果,這裡只是測試結果,其它的先不填寫。
設定映象佇列策略
在任意一個節點上執行:
root@mq-161:~ # rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
將所有佇列設定為映象佇列,即佇列會被複制到各個節點,各個節點狀態保持一直。
我們去live-mq-02上檢視策略。
[email protected]162:~ # rabbitmqctl list_policies
Listing policies ...
/ ha-all all ^ {"ha-mode":"all"} 0
...done.
此時映象叢集就已經完成了,可以在任意節點上建立佇列,看看其他兩個節點是否會同步。