RabbitMQ是一個開源的AMQP實現,服務器端用Erlang語言編寫,支持多種客戶端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用於在分佈式系統中存儲轉發消息,在易用性、擴展性、高可用性等方面表現不俗。node
AMQP,即Advanced message Queuing Protocol,高級消息隊列協議,是應用層協議的一個開放標準,爲面向消息的中間件設計。消息中間件主要用於組件之間的解耦,消息的發送者無需知道消息使用者的存在,反之亦然。linux
AMQP的主要特徵是面向消息、隊列、路由(包括點對點和發佈/訂閱)、可靠性、安全。segmentfault
經過 Erlang 的分佈式特性(經過 magic cookie 認證節點)進行 RabbitMQ 集羣,各 RabbitMQ 服務爲對等節點,即每一個節點都提供服務給客戶端鏈接,進行消息發送與接收。安全
這些節點經過 RabbitMQ HA 隊列(鏡像隊列)進行消息隊列結構複製。本方案中搭建 3 個節點,而且都是磁盤節點(全部節點狀態保持一致,節點徹底對等),只要有任何一個節點可以工做,RabbitMQ 集羣對外就能提供服務。服務器
首先在三臺主機上都安裝 Erlang
安裝 RabbitMQ Server
cookie
參考 個人另外一篇 Centos7.3 安裝 RabbitMQ 3.6app
臨時生效hostnamedom
命令格式分佈式
hostname <new hostname>
在三臺機器執行以下命令ui
192.168.252.101 $ hostname node1 192.168.252.102 $ hostname node2 192.168.252.103 $ hostname node3
查看修改後的hostname
$ hostname
永久更改hostname
編輯/etc/hosts
文件,添加到在三臺機器的/etc/hosts
中如下內容
$ vi /etc/hosts
192.168.252.101 node1 192.168.252.102 node2 192.168.252.103 node3
三臺主機上安裝的 RabbitMQ
都保證均可以正常啓動,才能夠進行如下操做
$ service rabbitmq-server stop Redirecting to /bin/systemctl stop rabbitmq-server.service
設置不一樣節點間同一認證的Erlang Cookie
這裏將 node1 的該文件複製到 node二、node3,因爲這個文件權限是 400爲方便傳輸,先修改權限,非必須操做,因此須要先修改 node二、node3 中的該文件權限爲 777
$ chmod 777 /var/lib/rabbitmq/.erlang.cookie
$ scp /var/lib/rabbitmq/.erlang.cookie node2:/var/lib/rabbitmq/ $ scp /var/lib/rabbitmq/.erlang.cookie node3:/var/lib/rabbitmq/
$ chmod 400 /var/lib/rabbitmq/.erlang.cookie $ chown rabbitmq /var/lib/rabbitmq/.erlang.cookie $ chgrp rabbitmq /var/lib/rabbitmq/.erlang.cookie
會提示輸入yes 和 密碼
cookie在全部節點上必須徹底同樣,同步時必定要注意。
erlang是經過主機名來鏈接服務,必須保證各個主機名之間能夠ping通。能夠經過編輯/etc/hosts來手工添加主機名和IP對應關係。若是主機名ping不通,rabbitmq服務啓動會失敗。
$ rabbitmqctl stop $ rabbitmq-server -detached
這個也能夠不執行,直接在節點服務器執行下邊的腳本,不過得保證這個rabbitmq服務是正常啓動的
node1 $ rabbitmqctl stop_app
按照順序執行 先node2
,node3
node2 $ rabbitmqctl stop_app # 中止rabbitmq服務 node2 $ rabbitmqctl join_cluster rabbit@node1 # node2和node1構成集羣, node2必須能經過node1的主機名ping通 node2 $ rabbitmqctl start_app # 開啓rabbitmq服務 node3 $ rabbitmqctl stop_app # 中止rabbitmq服務 node3 $ rabbitmqctl join_cluster rabbit@node1 # node3和node1構成集羣, node2必須能經過node1的主機名ping通 node3 $ rabbitmqctl start_app # 開啓rabbitmq服務
此時 node2 與 node3 也會自動創建鏈接
其中–ram
指的是做爲內存節點,要是想作爲磁盤節點的話,就不用加–ram
這個參數了
加入內存節點集羣
node2 # rabbitmqctl join_cluster --ram rabbit@node1
只要在節點列表裏包含了自己,它就成爲一個磁盤節點。
在RabbitMQ集羣裏,必須至少有一個磁盤節點存在。
node2 $ rabbitmqctl stop_app # 中止rabbitmq服務 node2 $ rabbitmqctl change_cluster_node_type ram # 更改節點爲內存節點 Turning rabbit@node2 into a ram node node2 $ rabbitmqctl change_cluster_node_type disc # 更改節點爲磁盤節點 Turning rabbit@node2 into a disc node node2 $ rabbitmqctl start_app # 開啓rabbitmq服務
執行完以後分別在每臺機器上查看節點狀態
[root@node1 ~]# rabbitmqctl cluster_status Cluster status of node rabbit@node1 [{nodes,[{disc,[rabbit@node1,rabbit@node2,rabbit@node3]}]}, {alarms,[{rabbit@node2,[]},{rabbit@node3,[]}]}]
[root@node2 ~]# rabbitmqctl cluster_status Cluster status of node rabbit@node2 [{nodes,[{disc,[rabbit@node1,rabbit@node2,rabbit@node3]}]}, {running_nodes,[rabbit@node3,rabbit@node2]}, {cluster_name,<<"rabbit@localhost">>}, {partitions,[]}, {alarms,[{rabbit@node3,[]},{rabbit@node2,[]}]}]
[root@node3 ~]# rabbitmqctl cluster_status Cluster status of node rabbit@node3 [{nodes,[{disc,[rabbit@node1,rabbit@node2,rabbit@node3]}]}, {running_nodes,[rabbit@node2,rabbit@node3]}, {cluster_name,<<"rabbit@localhost">>}, {partitions,[]}, {alarms,[{rabbit@node2,[]},{rabbit@node3,[]}]}]
第一行是集羣中的節點成員,disc表示這些都是磁盤節點
第二行是正在運行的節點成員
上面配置RabbitMQ默認集羣模式,但並不保證隊列的高可用性,儘管交換機、綁定這些能夠複製到集羣裏的任何一個節點,可是隊列內容不會複製,雖然該模式解決一部分節點壓力,但隊列節點宕機直接致使該隊列沒法使用,只能等待重啓,因此要想在隊列節點宕機或故障也能正常使用,就要複製隊列內容到集羣裏的每一個節點,須要建立鏡像隊列
鏡像隊列能夠同步queue和message,當主queue掛掉,從queue中會有一個變爲主queue來接替工做。
鏡像隊列是基於普通的集羣模式的,因此你仍是得先配置普通集羣,而後才能設置鏡像隊列。
鏡像隊列設置後,會分一個主節點和多個從節點,若是主節點宕機,從節點會有一個選爲主節點,原先的主節點起來後會變爲從節點。
queue和message雖然會存在全部鏡像隊列中,但客戶端讀取時不論物理面鏈接的主節點仍是從節點,都是從主節點讀取數據,而後主節點再將queue和message的狀態同步給從節點,所以多個客戶端鏈接不一樣的鏡像隊列不會產生同一message被屢次接受的狀況。
在普通集羣的中任意節點啓用策略,策略會自動同步到集羣節點
命令格式
set_policy [-p vhostpath] {name} {pattern} {definition} [priority]
在任意一個節點上執行
[root@node1 ~]# rabbitmqctl set_policy -p / ha-allqueue "^message" '{"ha-mode":"all"}' Setting policy "ha-allqueue" for pattern "^message" to "{\"ha-mode\":\"all\"}" with priority "0"
注意:"^message" 這個規則要根據本身修改,這個是指同步"message"開頭的隊列名稱,配置時使用的應用於全部隊列,因此表達式爲"^"
集羣重啓時,最後一個掛掉的節點應該第一個重啓,若是因特殊緣由(好比同時斷電),而不知道哪一個節點最後一個掛掉。可用如下方法重啓:
先在一個節點上執行
$ rabbitmqctl force_boot $ service rabbitmq-server start
在其餘節點上執行
$ service rabbitmq-server start
查看cluster狀態是否正常(要在全部節點上查詢)。
$ rabbitmqctl cluster_status
CentOs7.3 搭建 RabbitMQ 3.6 單機服務