1. 程式人生 > >Rabbitmq 相關介紹之單機集群配置

Rabbitmq 相關介紹之單機集群配置

rabbitmq 默認 集群模式

一、說明:

說到集群,大家應該都不陌生,為了提高性能需要配置集群,而在有的時候,我們需要在測試環境先測試然後灰度上線,所以這裏介紹在一臺服務器上配置rabbitmq集群

二、rabbitmq集群模式

1、普通模式:rabbitmq默認的集群模式

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個節點上進行存儲,從而在性能與高可用性之間取得一個平衡(應該就是指鏡像模式)。

2、鏡像模式:把需要的隊列做成鏡像隊列,存在於多個節點,屬於RabbitMQ的HA方案

該模式解決了上述問題,其實質和普通模式不同之處在於,消息實體會主動在鏡像節點間同步,而不是在consumer取數據時臨時拉取。該模式帶來的副作用也很明顯,除了降低系統性能外,如果鏡像隊列數量過多,加之大量的消息進入,集群內部的網絡帶寬將會被這種同步通訊大大消耗掉。所以在對可靠性要求較高的場合中適用,一個隊列想做成鏡像隊列,需要先設置policy,然後客戶端創建隊列的時候,rabbitmq集群根據“隊列名稱”自動設置是普通集群模式或鏡像隊列。具體如下:

隊列通過策略來使能鏡像。策略能在任何時刻改變,rabbitmq隊列也近可能的將隊列隨著策略變化而變化;非鏡像隊列和鏡像隊列之間是有區別的,前者缺乏額外的鏡像基礎設施,沒有任何slave,因此會運行得更快。

為了使隊列稱為鏡像隊列,你將會創建一個策略來匹配隊列,設置策略有兩個鍵“ha-mode和 ha-params(可選)”。ha-params根據ha-mode設置不同的值,下面表格說明這些key的選項,如下圖:

技術分享

以上概念參考地址:http://www.ywnds.com/?p=4741

三、普通集群模式安裝配置

官方文檔https://www.rabbitmq.com/clustering.html

1、環境
CentOS 6.7    IP 172.16.100.94   x86_64
2、軟件包版本:
erlang-20.0.4-1.el6.x86_64.rpm
rabbitmq-server-3.6.12-1.el6.noarch.rpm
3、安裝
#rpm -ivh  erlang-20.0.4-1.el6.x86_64.rpm
#yum install socat  -y   # rabbitmq-server依賴次軟件包
#rpm -ivh rabbitmq-server-3.6.12-1.el6.noarch.rpm
4、啟動3個進程(模擬3臺不同的node)
#RABBITMQ_NODE_PORT=5672 RABBITMQ_NODENAME=rabbit1 /etc/init.d/rabbitmq-server start 
#RABBITMQ_NODE_PORT=5673 RABBITMQ_NODENAME=rabbit2 /etc/init.d/rabbitmq-server start 
#RABBITMQ_NODE_PORT=5674 RABBITMQ_NODENAME=rabbit3 /etc/init.d/rabbitmq-server start 
查看啟動情況
#netstat -tunlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name     
tcp        0      0 0.0.0.0:25672               0.0.0.0:*                   LISTEN      25527/beam.smp      
tcp        0      0 0.0.0.0:25673               0.0.0.0:*                   LISTEN      26425/beam.smp            
tcp        0      0 0.0.0.0:25674               0.0.0.0:*                   LISTEN      27310/beam.smp      
tcp        0      0 0.0.0.0:4369                0.0.0.0:*                   LISTEN      25191/epmd                 
tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN      1778/sshd                          
tcp        0      0 :::5672                     :::*                        LISTEN      25527/beam.smp      
tcp        0      0 :::5673                     :::*                        LISTEN      26425/beam.smp      
tcp        0      0 :::5674                     :::*                        LISTEN      27310/beam.smp               
tcp        0      0 :::4369                     :::*                        LISTEN      25191/epmd          
tcp        0      0 :::22                       :::*                        LISTEN      1778/sshd  
5、結束進程命令
#rabbitmqctl -n rabbit1 stop
#rabbitmqctl -n rabbit2 stop
#rabbitmqctl -n rabbit3 stop
6、查看狀態:
#rabbitmqctl -n rabbit1 cluster_status
Cluster status of node [email protected]
[{nodes,[{disc,[[email protected]]}]},
 {running_nodes,[[email protected]]},
 {cluster_name,<<"[email protected]">>},
 {partitions,[]},
 {alarms,[{[email protected],[]}]}]
#rabbitmqctl -n rabbit2 cluster_status
Cluster status of node [email protected]
[{nodes,[{disc,[[email protected]]}]},
 {running_nodes,[[email protected]]},
 {cluster_name,<<"[email protected]">>},
 {partitions,[]},
 {alarms,[{[email protected],[]}]}]
#rabbitmqctl -n rabbit3 cluster_status
Cluster status of node [email protected]
[{nodes,[{disc,[[email protected]]}]},
 {running_nodes,[[email protected]]},
 {cluster_name,<<"[email protected]">>},
 {partitions,[]},
 {alarms,[{[email protected],[]}]}]
7、開始配置
停掉rabbit2節點的應用
#rabbitmqctl -n rabbit2 stop_app
Stopping rabbit application on node [email protected]
將rabbit2節點加入到[email protected]
#rabbitmqctl -n rabbit2 join_cluster [email protected]
Clustering node [email protected] with [email protected]
啟動rabbit2應用節點
#rabbitmqctl -n rabbit2 start_app
Starting node [email protected]
查看集群狀態
#rabbitmqctl -n rabbit1 cluster_status
Cluster status of node [email protected]
[{nodes,[{disc,[[email protected],[email protected]]}]},
 {running_nodes,[[email protected],[email protected]]},
 {cluster_name,<<"[email protected]">>},
 {partitions,[]},
 {alarms,[{[email protected],[]},{[email protected],[]}]}]
 
#rabbitmqctl -n rabbit2 cluster_status
Cluster status of node [email protected]
[{nodes,[{disc,[[email protected],[email protected]]}]},
 {running_nodes,[[email protected],[email protected]]},
 {cluster_name,<<"[email protected]">>},
 {partitions,[]},
 {alarms,[{[email protected],[]},{[email protected],[]}]}]
可以看到不管是以哪一個節點的身份去查,集群中都有節點rabbit1和rabbit2
#############################################3
現在加入rabbit3
首先停掉rebbit3節點的應用
# rabbitmqctl -n rabbit3 stop_app
Stopping rabbit application on node [email protected]

# rabbitmqctl -n rabbit3 join_cluster [email protected]
Clustering node [email protected] with [email protected]
啟動
# rabbitmqctl -n rabbit3 start_app
Starting node [email protected]
查看集群狀態
#rabbitmqctl -n rabbit1 cluster_status
Cluster status of node [email protected]
[{nodes,[{disc,[[email protected],[email protected],[email protected]]}]},
 {running_nodes,[[email protected],[email protected],[email protected]]},
 {cluster_name,<<"[email protected]">>},
 {partitions,[]},
 {alarms,[{[email protected],[]},
          {[email protected],[]},
          {[email protected],[]}]}]
註:已經加入群集的節點可以隨時停止,並且宕機對集群來說也是沒事的,在這兩種情況下,集群的其
余部分繼續運行不受影響,並且節點在重新啟動時會自動“趕上”其他集群節點。

四、對集群進行測試:

我們假設關閉rabbit1和rabbit3,在每一個步驟檢查集群狀態
1、關閉rabbit1節點
#rabbitmqctl -n rabbit1 stop             
Stopping and halting node [email protected]
2、查看集群狀態
# rabbitmqctl -n rabbit2 cluster_status
Cluster status of node [email protected]
[{nodes,[{disc,[[email protected],[email protected],[email protected]]}]},
 {running_nodes,[[email protected],[email protected]]},
 {cluster_name,<<"[email protected]">>},
 {partitions,[]},
 {alarms,[{[email protected],[]},{[email protected],[]}]}]    
可以看到rabbit1節點已經不再running_noeds中了,但是依然在disc列表!
#rabbitmqctl -n rabbit3 cluster_status
Cluster status of node [email protected]
[{nodes,[{disc,[[email protected],[email protected],[email protected]]}]},
 {running_nodes,[[email protected],[email protected]]},
 {cluster_name,<<"[email protected]">>},
 {partitions,[]},
 {alarms,[{[email protected],[]},{[email protected],[]}]}]
############################################################
# rabbitmqctl -n rabbit3 stop    #關閉rabbit3 節點
Stopping and halting node [email protected]
3、查看集群狀態
# rabbitmqctl -n rabbit2 cluster_status
Cluster status of node [email protected]
[{nodes,[{disc,[[email protected],[email protected],[email protected]]}]},
 {running_nodes,[[email protected]]},
 {cluster_name,<<"[email protected]">>},
 {partitions,[]},
 {alarms,[{[email protected],[]}]}]
4、現在開啟關閉的節點rabbit1 和rabbit3 
#RABBITMQ_NODE_PORT=5672 RABBITMQ_NODENAME=rabbit1 /etc/init.d/rabbitmq-server start
#RABBITMQ_NODE_PORT=5674 RABBITMQ_NODENAME=rabbit3 /etc/init.d/rabbitmq-server start

5、再查看集群狀態
#rabbitmqctl -n rabbit1 cluster_status
Cluster status of node [email protected]
[{nodes,[{disc,[[email protected],[email protected],[email protected]]}]},
 {running_nodes,[[email protected],[email protected],[email protected]]},
 {cluster_name,<<"[email protected]">>},
 {partitions,[]},
 {alarms,[{[email protected],[]},
          {[email protected],[]},
          {[email protected],[]}]}]
可以看到3個節點都已經是running狀態了。
一些註意事項:
當整個群集被關閉時,最後一個節點必須是要聯機的第一個節點。如果沒有發生這種情況,節點將等待
30秒鐘,最後一個disc節點重新聯機,之後會失敗。如果最後一個要脫機的節點無法恢復,則可以使用
forget_cluster_node命令將其從集群中刪除。如果所有群集節點都以同時和不受控制的方式停止
(例如斷電),你可以留下一種情況,所有的節點都認為一些其他節點在它們之後停止,在這種情況下
您可以在一個節點上使用force_boot命令,使其再次可引導。
6、為rabbit1節點添加用戶名
#rabbitmqctl -n rabbit1 add_user admin admin123
#rabbitmqctl -n rabbit1 set_user_tags admin administrator
#rabbitmqctl -n rabbit1 set_permissions -p / admin  ".*" ".*" ".*"
7、開啟web管理界面
#rabbitmq-plugins -n rabbit1 enable rabbitmq_management   #會開啟15672端口
在瀏覽器訪問  輸入第6步設置的用戶名和密碼,界面如下:

技術分享

註:rabbit2和rabbit3之所以是黃色狀態,紅色小箭頭也解釋了。因為我們是在一臺服務器模擬的3個節點,rabbitmq_management界面啟動之後,端口是15672,只啟動了一個,再啟動rabbit2的時候,提示端口被占用,目前不知道如何為管理界面指定不同的端口,後面會繼續研究……

本文出自 “知識體系” 博客,請務必保留此出處http://linuxg.blog.51cto.com/4410110/1965369

Rabbitmq 相關介紹之單機集群配置