環境:html
OS:CentOS6.75node
RabbitMQ Vervison :3.6.5web
節點:正則表達式
node1 : mq01 172.16.42.128bash
node2: mq02 172.16.42.135
cookie
配置:
網絡
一、兩臺機器上都安裝RabbitMQapp
這裏的安裝包括socat、Erlang、rabbitmq-server包的安裝,已經環境變量和config文件的配置,請參考RabbitMQ安裝,先不要急着建立用戶、虛擬主機和配置權限。這些等集羣建立好了再作dom
二、配置hosts文件ide
更改兩臺MQ節點的計算機名分別爲mq01 和mq02,而後修改hosts配置文件
mq01
[root@mq01 ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 172.16.42.128 mq01 172.16.42.135 mq02
mq02
[root@mq01 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 172.16.42.128 mq01 172.16.42.135 mq02
三、拷貝erlang.cookie
Rabbitmq的集羣是依附於erlang的集羣來工做的,因此必須先構建起erlang的集羣景象。Erlang的集羣中各節點是經由過程一個magic cookie來實現的,這個cookie存放在/var/lib/rabbitmq/.erlang.cookie中(像個人root用戶安裝的就是放在個人root/.erlang.cookie中),文件是400的權限。因此必須包管各節點cookie對峙一致,否則節點之間就沒法通訊。
[root@mq01 ~]# cat /var/lib/rabbitmq/.erlang.cookie FNMCAWWQGOJIQKDJQUQG
將cookie中的內容複製到mq02的cookie文件中。
四、啓動rabbitmq服務
/etc/init.d/rabbitmq-server start
在node2 mq02上中止rabbitmq應用程序,並重置(重置只是清除節點的配置,若是沒有配置過,則能夠省略),而後加入node1集羣
[root@mq02 rabbitmq]# rabbitmqctl stop_app Stopping node rabbit@mq02 ...
reset節點
rabbitmqctl reset
[root@mq02 rabbitmq]# rabbitmqctl reset Resetting node rabbit@mq02 ...
五、加入集羣
rabbitmqctl join_cluster rabbit@mq01
[root@mq02 ~]# rabbitmqctl join_cluster rabbit@mq01 Clustering node rabbit@mq02 with rabbit@mq01 ...
啓動rabbitmq應用
[root@mq02 ~]# rabbitmqctl start_app Starting node rabbit@mq02 ...
六、查看集羣狀態
node2上查看集羣狀態
rabbitmqctl cluster_status
[root@mq02 ~]# rabbitmqctl cluster_status Cluster status of node rabbit@mq02 ... [{nodes,[{disc,[rabbit@mq01,rabbit@mq02]}]}, {running_nodes,[rabbit@mq01,rabbit@mq02]}, {cluster_name,<<"rabbit@mq01">>}, {partitions,[]}, {alarms,[{rabbit@mq01,[]},{rabbit@mq02,[]}]}]
node1上查看集羣狀態
[root@mq01 ~]# rabbitmqctl cluster_status Cluster status of node rabbit@mq01 ... [{nodes,[{disc,[rabbit@mq01,rabbit@mq02]}]}, {running_nodes,[rabbit@mq02,rabbit@mq01]}, {cluster_name,<<"rabbit@mq01">>}, {partitions,[]}, {alarms,[{rabbit@mq02,[]},{rabbit@mq01,[]}]}]
七、更改節點類型
節點有兩種類型:磁盤節點和內存節點,集羣中必須至少有一個磁盤節點,不然隊列元數據沒法寫入到集羣中,當磁盤節點宕掉時,集羣將沒法寫入新的隊列元數據信息。
從上面集羣狀態能夠看出,mq01和mq02 均爲磁盤節點,能夠經過命令
rabbitmqctl change_cluster_node_type disc
將mq02更改成內存節點
[root@mq02 ~]# rabbitmqctl stop_app Stopping node rabbit@mq02 ... [root@mq02 ~]# rabbitmqctl change_cluster_node_type ram Turning rabbit@mq02 into a ram node ... [root@mq02 ~]# rabbitmqctl start_app Starting node rabbit@mq02 ... [root@mq02 ~]# rabbitmqctl cluster_status Cluster status of node rabbit@mq02 ... [{nodes,[{disc,[rabbit@mq01]},{ram,[rabbit@mq02]}]}, {running_nodes,[rabbit@mq01,rabbit@mq02]}, {cluster_name,<<"rabbit@mq01">>}, {partitions,[]}, {alarms,[{rabbit@mq01,[]},{rabbit@mq02,[]}]}]
也能夠在將mq02 加入集羣只帶上--ram參數,即設置mq02爲內存節點.
注意:更改節點類型前,必須將節點rabbitmq應用停掉。
八、驗證節點crash後又恢復時,是否能自動加入集羣
將node2 mq02 服務停掉,在node1上查看集羣狀態
[root@mq02 ~]# rabbitmqctl stop Stopping and halting node rabbit@mq02 ...
node1 上查看集羣狀態
[root@mq01 ~]# rabbitmqctl cluster_status Cluster status of node rabbit@mq01 ... [{nodes,[{disc,[rabbit@mq01]},{ram,[rabbit@mq02]}]}, {running_nodes,[rabbit@mq01]}, {cluster_name,<<"rabbit@mq01">>}, {partitions,[]}, {alarms,[{rabbit@mq01,[]}]}]
從上面能夠看到running_nodes 只有node1了
啓動node2的服務
[root@mq02 ~]# /etc/init.d/rabbitmq-server start Starting rabbitmq-server: SUCCESS rabbitmq-server.
再來查看兩臺機器集羣狀態
[root@mq01 ~]# rabbitmqctl cluster_status Cluster status of node rabbit@mq01 ... [{nodes,[{disc,[rabbit@mq01]},{ram,[rabbit@mq02]}]}, {running_nodes,[rabbit@mq02,rabbit@mq01]}, {cluster_name,<<"rabbit@mq01">>}, {partitions,[]}, {alarms,[{rabbit@mq02,[]},{rabbit@mq01,[]}]}]
[root@mq02 ~]# rabbitmqctl cluster_status Cluster status of node rabbit@mq02 ... [{nodes,[{disc,[rabbit@mq01]},{ram,[rabbit@mq02]}]}, {running_nodes,[rabbit@mq01,rabbit@mq02]}, {cluster_name,<<"rabbit@mq01">>}, {partitions,[]}, {alarms,[{rabbit@mq01,[]},{rabbit@mq02,[]}]}]
九、當磁盤節點掛了時
將node1erlang虛擬機停掉
[root@mq01 ~]# rabbitmqctl stop
Stopping and halting node rabbit@mq01 ...
登陸rabbitmq web管理控制檯,建立新的隊列,報錯
恢復node1 erlang虛擬機服務
[root@mq01 ~]# /etc/init.d/rabbitmq-server start
Starting rabbitmq-server: SUCCESS
rabbitmq-server.
從新建立隊列,成功
十、當磁盤節點掛了時
將node2 erlang虛擬機停掉
[root@mq02 ~]# rabbitmqctl stop
Stopping and halting node rabbit@mq02 ...
登陸node1的web管理控制檯,建立新的隊列,成功
總結:
結合9 和10 的測試來看,集羣中沒有沒有磁盤節點,那麼集羣不能建立新的隊列元數據,可是仍能繼續工做,若是內存幾點掛了,則集羣不受影響,這也是爲何集羣中至少要有一個磁盤節點的緣由,單個節點不能設置爲內存節點。
十一、集羣鏡像模式
上面的集羣模式爲普通模式,鏡像模式實在普通模式的基礎之上加一些策略。其實質和普通模式不一樣之處在於,消息實體會主動在鏡像節點間同步,而不是在consumer取數據時臨時拉取。該模式帶來的反作用也很明顯,除了下降系統性能外,若是鏡像隊列數量過多,加之大量的消息進入,集羣內部的網絡帶寬將會被這種同步通信大大消耗掉。因此在對可靠性要求較高的場合中適用,一個隊列想作成鏡像隊列,須要先設置policy,而後客戶端建立隊列的時候,rabbitmq集羣根據「隊列名稱」自動設置是普通集羣模式或鏡像隊列。具體以下:
隊列經過策略來使能鏡像。策略能在任什麼時候刻改變,rabbitmq隊列也近可能的將隊列隨着策略變化而變化;非鏡像隊列和鏡像隊列之間是有區別的,前者缺少額外的鏡像基礎設施,沒有任何slave,所以會運行得更快。爲了使隊列稱爲鏡像隊列,你將會建立一個策略來匹配隊列,設置策略有兩個鍵「ha-mode和 ha-params(可選)」。ha-params根據ha-mode設置不一樣的值,下面表格說明這些key的選項:
語法講解:
在cluster中任意節點啓用策略,策略會自動同步到集羣節點
rabbitmqctl set_policy -p hrsystem ha-allqueue"^" '{"ha-mode":"all"}'
這行命令在vhost名稱爲hrsystem建立了一個策略,策略名稱爲ha-allqueue,策略模式爲 all 即複製到全部節點,包含新增節點,策略正則表達式爲 「^」 表示全部匹配全部隊列名稱。
例如rabbitmqctl set_policy -p hrsystem ha-allqueue "^message" '{"ha-mode":"all"}'
注意:"^message" 這個規則要根據本身修改,這個是指同步"message"開頭的隊列名稱,咱們配置時使用的應用於全部隊列,因此表達式爲"^"
官方set_policy說明參見
set_policy [-p vhostpath] {name} {pattern} {definition} [priority]
(http://www.rabbitmq.com/man/rabbitmqctl.1.man.html)
建立策略
set_policy [-p vhostpath] {name} {pattern} {definition} [priority]
[root@mq02 ~]# rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}' Setting policy "ha-all" for pattern "^" to "{\"ha-mode\":\"all\"}" with priority "0" ...
查看策略:
[root@mq01 ~]# rabbitmqctl list_policies Listing policies ... / ha-all all ^ {"ha-mode":"all"} 0
注意:前面建立策略時沒有指定vhost,則對默認的/ 虛擬主機建立策略
十二、將節點移出集羣
將節點node2 移出集羣前,先要stop_app,人後reset節點。
[root@mq02 ~]# rabbitmqctl stop_app Stopping node rabbit@mq02 ... [root@mq02 ~]# rabbitmqctl reset Resetting node rabbit@mq02 ... [root@mq02 ~]# rabbitmqctl cluster_status Cluster status of node rabbit@mq02 ... [{nodes,[{disc,[rabbit@mq02]}]},{alarms,[]}]
node1上查看集羣狀態
[root@mq01 ~]# rabbitmqctl cluster_status Cluster status of node rabbit@mq01 ... [{nodes,[{disc,[rabbit@mq01]}]}, {running_nodes,[rabbit@mq01]}, {cluster_name,<<"rabbit@mq01">>}, {partitions,[]}, {alarms,[{rabbit@mq01,[]}]}]
查看策略,仍然存在。
[root@mq01 ~]# rabbitmqctl list_policies Listing policies ... / ha-all all ^ {"ha-mode":"all"} 0
移除遠程offline的節點
rabbitmqctl forget_cluster_node rabbit@mq02
上面的方法是在節點本地執行命令,將節點從集羣中刪除,可是若是節點出現故障,連不上節點時,就沒法用這種方式刪除節點了,咱們能夠從遠程節點刪除該節點
注意:必須是遠程節點offline時,才能執行執行此命令刪除節點。不然報錯
一、在node2 上停掉rabbitmq應用
[root@mq02 ~]# rabbitmqctl stop_app Stopping node rabbit@mq02 ...
二、在node1上執行刪除節點命令,而後查看集羣狀態
[root@mq01 ~]# rabbitmqctl forget_cluster_node rabbit@mq02 Removing node rabbit@mq02 from cluster ... [root@mq01 ~]# rabbitmqctl cluster_status Cluster status of node rabbit@mq01 ... [{nodes,[{disc,[rabbit@mq01]}]}, {running_nodes,[rabbit@mq01]}, {cluster_name,<<"my_cluster">>}, {partitions,[]}, {alarms,[{rabbit@mq01,[]}]}]
1三、集羣上建立帳號
rabbitmqctl add_user user_name
[root@mq02 ~]# rabbitmqctl add_user spms 123456 Creating user "spms" ... [root@mq02 ~]# rabbitmqctl list_users Listing users ... spms [] guest [administrator]
[root@mq01 ~]# rabbitmqctl list_users Listing users ... spms [] guest [administrator]
能夠看到,在任意節點上建立的帳號,會同步到其餘節點上
1四、集羣中建立vhost
rabbitmqctl add_vhost vhost_name
[root@mq01 ~]# rabbitmqctl add_vhost spms Creating vhost "spms" ... [root@mq01 ~]# rabbitmqctl list_vhosts Listing vhosts ... spms /
[root@mq02 ~]# rabbitmqctl list_vhosts Listing vhosts ... spms /
能夠看到,在任意節點上建立的vhost,會同步到其餘節點上
1五、設置vhost權限
rabbitmqctl set_permissions -p vhost_name username conf write read
[root@mq02 ~]# rabbitmqctl set_permissions -p spms spms '.*' '.*' '.*' Setting permissions for user "spms" in vhost "spms" ... [root@mq02 ~]# rabbitmqctl list_permissions Listing permissions in vhost "/" ... guest .* .* .* [root@mq02 ~]# rabbitmqctl list_permissions -p spms Listing permissions in vhost "spms" ... spms .* .* .*
[root@mq01 ~]# rabbitmqctl list_permissions Listing permissions in vhost "/" ... guest .* .* .* [root@mq01 ~]# rabbitmqctl list_permissions -p spms Listing permissions in vhost "spms" ... spms .* .* .*
1六、設置cluster_name
rabbitmqctl set_cluster_name cluster_name
[root@mq02 ~]# rabbitmqctl set_cluster_name my_cluster Setting cluster name to my_cluster ... [root@mq02 ~]# rabbitmqctl cluster_status Cluster status of node rabbit@mq02 ... [{nodes,[{disc,[rabbit@mq01,rabbit@mq02]}]}, {running_nodes,[rabbit@mq01,rabbit@mq02]}, {cluster_name,<<"my_cluster">>}, {partitions,[]}, {alarms,[{rabbit@mq01,[]},{rabbit@mq02,[]}]}]