1. 程式人生 > >RabbitMQ兩種叢集模式配置管理

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.

此時映象叢集就已經完成了,可以在任意節點上建立佇列,看看其他兩個節點是否會同步。