一、 功能和原理介紹
RabbitMQ是一個開源的AMQP實現,服務器端用Erlang語言編寫,支持多種客戶端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用於在分布式系統中存儲轉發消息,在易用性、擴展性、高可用性等方面表現不俗。
AMQP,即Advanced message Queuing Protocol,高級消息隊列協議,是應用層協議的一個開放標准,為面向消息的中間件設計。消息中間件主要用於組件之間的解耦,消息的發送者無需知道消息使用者的存在,反之亦然。
AMQP的主要特征是面向消息、隊列、路由(包括點對點和發布/訂閱)、可靠性、安全。
1、設計集群的目的
a、 允許消費者和生產者在RabbitMQ節點崩潰的情況下繼續運行
b、 通過增加更多的節點來擴展消息通信的吞吐量
2、 集群配置方式
RabbitMQ可以通過三種方法來部署分布式集群系統,分別是:cluster,federation,shovel
cluster: 不支持跨網段,用於同一個網段內的局域網, 可以隨意的動態增加或者減少, 節點之間需要運行相同版本的RabbitMQ和Erlang
federation:應用於廣域網,允許單台服務器上的交換機或隊列接收發布到另一台服務器上交換機或隊列的消息,可以是單獨機器或集群。federation隊列類似於單向點對點連接,消息會在聯盟隊列之間轉發任意次,直到被消費者接受。通常使用federation來連接internet上的中間服務器,用作訂閱分發消息或工作隊列。
shovel:連接方式與federation的連接方式類似,但它工作在更低層次。可以應用於廣域網。
3、 節點類型
RAM node:內存節點將所有的隊列、交換機、綁定、用戶、權限和vhost的元數據定義存儲在內存中,好處是可以使得像交換機和隊列聲明等操作更加的快速。
Disk node:將元數據存儲在磁盤中,單節點系統只允許磁盤類型的節點,防止重啟RabbitMQ的時候,丟失系統的配置信息。
4、 Erlang Cookie
保證不同節點可以相互通信的密鑰,要保證集群中的不同節點相互通信必須共享相同的Erlang Cookie。具體的目錄存放在/var/lib/rabbitmq/.erlang.cookie
RabbitMQ底層是通過Erlang架構來實現的,所以rabbitmqctl會啟動Erlang節點,並基於Erlang節點來使用Erlang系統連接RabbitMQ節點,在連接過程中需要正確的Erlang Cookie和節點名稱,Erlang節點通過交換Erlang Cookie以獲得認證。
5、集群模式
RabbitMQ的Cluster集群模式一般分為兩種,普通模式和鏡像模式。
普通模式:默認的集群模式,以兩個節點(rabbit01、rabbit02)為例來進行說明。對於Queue來說,消息實體只存在於其中一個節點rabbit01(或者rabbit02),rabbit01和rabbit02兩個節點僅有相同的元數據,即隊列的結構。當消息進入rabbit01節點的Queue后,consumer從rabbit02節點消費時,RabbitMQ會臨時在rabbit01、rabbit02間進行消息傳輸,把A中的消息實體取出並經過B發送給consumer。所以consumer應盡量連接每一個節點,從中取消息。即對於同一個邏輯隊列,要在多個節點建立物理Queue。否則無論consumer連rabbit01或rabbit02,出口總在rabbit01,會產生瓶頸。當rabbit01節點故障后,rabbit02節點無法取到rabbit01節點中還未消費的消息實體。如果做了消息持久化,那么得等rabbit01節點恢復,然后才可被消費;如果沒有持久化的話,就會產生消息丟失的現象。
鏡像模式:將需要消費的隊列變為鏡像隊列,存在於多個節點,這樣就可以實現RabbitMQ的HA高可用性。作用就是消息實體會主動在鏡像節點之間實現同步,而不是像普通模式那樣,在consumer消費數據時臨時讀取。缺點就是,集群內部的同步通訊會占用大量的網絡帶寬。
鏡像隊列實現了RabbitMQ的高可用性(HA),具體的實現策略如下所示:
語法講解:
在cluster中任意節點啟用策略,策略會自動同步到集群節點
#rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}' # 應用於說有的隊列,所以表達式為“^”
6、端口
TCP 4369:用於集群鄰居發現;
TCP 5671、5672:用於AMQP clients使用;
TCP 15672:用於http api與rabbitadmin訪問,后者僅限在management plugin開啟時;
TCP 25672:用於erlang分布式節點/工具通信
二、部署
1、單節點部署
a、包安裝
# yum install rabbitmq-server.noarch
# 配置文件在: /etc/rabbitmq/rabbitmq.config 配置文件使用 “%%” 注釋配置
b、啟動服務,設置開機自啟動
# systemctl enable rabbitmq-server.service
# systemctl start rabbitmq-server.service
c、查看狀態
# systemctl status rabbitmq-server.service -l
d、RABBITMQ頁面(web)管理
management plugin默認就在RabbitMQ的發布版本中,
啟用web插件
# rabbitmq-plugins enable rabbitmq_management
關閉web插件
# rabbitmq-plugins disable rabbitmq_management
瀏覽器訪問:http://rabbitmq-server-IP:15672 如下圖,賬號密碼隨后創建。
e、Management plugin登錄賬號管理 (如果是集群,在一個節點修改,便可以全部生效,配置文件不會同步)
1、查看用戶
# rabbitmqctl list_users
2、 guest賬號
rabbit默認只有guest賬號,可以使用guest:guest 登錄web
3、CLI創建登錄賬號
# rabbitmqctl add_user username RABBIT_PASS (語法)
4、 設置賬號的屬性
# rabbitmqctl set_user_tags username administrator #用戶設置為管理員角色
# rabbitmqctl set_permissions username ".*" ".*" ".*" #分配權限
5、登錄
f、查看端口
--------------------到此,單節點配置完成。
2、集群部署--普通模式
a、環境
三台主機。系統: CentOS Linux release 7.4.1708 (Core)
主機名 IP 節點類型
cehp1 10.6.32.20 Master-Disk node
ceph2 10.6.32.21 slave-RAM node
ceph3 10.6.32.22 slave-RAM node
b、關閉從節點服務 (ceph2 、ceph3)
# rabbitmqctl stop
# systemctl stop rabbitmq-server.service
c、設置不同節點間同一認證的Erlang Cookie
采用從主節點copy的方式保持Cookie的一致性
# scp /var/lib/rabbitmq/.erlang.cookie root@ceph2:/var/lib/rabbitmq/.erlang.cookie
# scp /var/lib/rabbitmq/.erlang.cookie root@ceph3:/var/lib/rabbitmq/.erlang.cookie
d、啟用節點,並查詢狀態
# rabbitmq-server -detached
# rabbitmqctl cluster_status
e、組建集群(ceph2、cehp3)
# rabbitmqctl stop_app
# rabbitmqctl join_cluster rabbit@ceph1 (rabbit代表集群名,ceph1代表集群節點,如果需要使用內存節點,增加一個”--ram“的參數即可,例:" rabbitmqctl join_cluster --ram rabbit@ceph1")
# rabbitmqctl start_app
# rabbitmqctl cluster_status
可以看出,加入集群后默認均為 disc node
f、修改 disc node 到 ram node
# rabbitmqctl stop_app
# rabbitmqctl change_cluster_node_type ram #(需要修改那個節點便在那個節點執行操作)
# rabbitmqctl start_app
g、web 查看狀態
如果需要在web 看到從節點信息,需要在從節點上也開啟web插件。
--------到此,默認集群配置完成。
維護:
如果要退出集群
1、從節點:(ceph3 為例)
#rabbitmqctl stop_app
# rabbitmqctl reset
# rabbitmqctl start_app
2、在集群主節點查看:
# rabbitmqctl cluster_status
3、鏡像集群
在集群中執行即可
# rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}' # #所有隊列都進行鏡像
4、rabbitmq-web Haproxy 配置
#--------------------------------------------------------------------- # listen Rabbitmq-cluster-web server #--------------------------------------------------------------------- listen rabbitmq-web mode tcp bind 10.6.32.254:15671 balance roundrobin server controller1 10.6.32.20:15672 check inter 2000 rise 2 fall 5 server controller2 10.6.32.21:15672 check inter 2000 rise 2 fall 5 server controller3 10.6.32.22:15672 check inter 2000 rise 2 fall 5
openstack nova 調用 openstack:
# vim /etc/nova/nova.conf
[DEFAULT]
transport_url = rabbit://rabbitmq-username:RABBIT_PASS@controller1:5672,rabbitmq-username:RABBIT_PASS@controller2:5672,rabbitmq-username:RABBIT_PASS@controller3:5672
謝謝