概述
一般來說晃财,如果只是為了學(xué)習(xí)RabbitMQ或者驗證業(yè)務(wù)工程的正確性那么在本地環(huán)境或者測試環(huán)境上使用其單實例部署就可以了,但是出于MQ中間件本身的可靠性建炫、并發(fā)性畦韭、吞吐量和消息堆積能力等問題的考慮,在生產(chǎn)環(huán)境上一般都會考慮使用RabbitMQ的集群方案肛跌。
一. RabbitMQ集群方案的原理
RabbitMQ本身是基于Erlang編寫艺配,Erlang語言天生具備分布式特性(通過同步Erlang集群各節(jié)點的erlang.cookie來實現(xiàn))。因此衍慎,RabbitMQ天然支持集群转唉。集群是保證可靠性的一種方式,同時可以通過水平擴展以達到增加消息吞吐量能力的目的稳捆。
下圖為集群的示例:
上面圖中采用三個節(jié)點組成了一個RabbitMQ的集群赠法,Exchange A(交換器)的元數(shù)據(jù)信息在所有節(jié)點上是一致的,而Queue(存放消息的隊列)的完整數(shù)據(jù)則只會存在于它所創(chuàng)建的那個節(jié)點上乔夯。砖织,其他節(jié)點只知道這個queue的metadata信息和一個指向queue的owner node的指針。
二. RabbitMQ集群元數(shù)據(jù)的同步
RabbitMQ集群會始終同步四種類型的內(nèi)部元數(shù)據(jù):
- 隊列元數(shù)據(jù):隊列名稱和它的屬性
- 交換器元數(shù)據(jù):交換器名稱驯嘱、類型和屬性
- 綁定元數(shù)據(jù):一張簡單的表格展示了如何將消息路由到隊列
- vhost元數(shù)據(jù):為vhost內(nèi)的隊列镶苞、交換器和綁定提供命名空間和安全屬性
因此,當(dāng)用戶訪問其中任何一個RabbitMQ節(jié)點時鞠评,通過rabbitmqctl查詢到的queue/user/exchange/vhost等信息都是相同的茂蚓。
為何RabbitMQ集群僅采用元數(shù)據(jù)同步的方式?
存儲空間。如果每個集群節(jié)點都擁有所有Queue的完全數(shù)據(jù)拷貝剃幌,那么每個節(jié)點的存儲空間會非常大聋涨,集群的消息積壓能力會非常弱(無法通過集群節(jié)點的擴容提高消息積壓能力);
性能负乡。消息的發(fā)布者需要將消息復(fù)制到每一個集群節(jié)點牍白,對于持久化消息,網(wǎng)絡(luò)和磁盤同步復(fù)制的開銷都會明顯增加抖棘。
三. RabbitMQ集群發(fā)送/訂閱消息的基本原理
RabbitMQ集群的工作原理圖如下:
客戶端直接連接隊列所在節(jié)點
如果有一個消息生產(chǎn)者或者消息消費者通過amqp-client的客戶端連接至節(jié)點1進行消息的發(fā)布或者訂閱茂腥,那么此時的集群中的消息收發(fā)只與節(jié)點1相關(guān)。
客戶端連接的是非隊列數(shù)據(jù)所在節(jié)點
如果消息生產(chǎn)者所連接的是節(jié)點2或者節(jié)點3切省,此時隊列1的完整數(shù)據(jù)不在該兩個節(jié)點上最岗,那么在發(fā)送消息過程中這兩個節(jié)點主要起了一個路由轉(zhuǎn)發(fā)作用,根據(jù)這兩個節(jié)點上的元數(shù)據(jù)轉(zhuǎn)發(fā)至節(jié)點1上朝捆,最終發(fā)送的消息還是會存儲至節(jié)點1的隊列1上般渡。同樣,如果消息消費者所連接的節(jié)點2或者節(jié)點3,那這兩個節(jié)點也會作為路由節(jié)點起到轉(zhuǎn)發(fā)作用驯用,將會從節(jié)點1的隊列1中拉取消息進行消費脸秽。
四. 集群節(jié)點類型
1. 磁盤節(jié)點
將配置信息和元信息存儲在磁盤上(單節(jié)點系統(tǒng)必須是磁盤節(jié)點,否則每次重啟RabbitMQ之后所有的系統(tǒng)配置信息都會丟失)蝴乔。
2. 內(nèi)存節(jié)點
將配置信息和元信息存儲在內(nèi)存中记餐。性能是優(yōu)于磁盤節(jié)點的。
RabbitMQ要求集群中至少有一個磁盤節(jié)點薇正,當(dāng)節(jié)點加入和離開集群時剥扣,必須通知磁盤節(jié)點(如果集群中唯一的磁盤節(jié)點崩潰了,則不能進行創(chuàng)建隊列铝穷、創(chuàng)建交換器、創(chuàng)建綁定佳魔、添加用戶曙聂、更改權(quán)限、添加和刪除集群節(jié)點)鞠鲜∧梗總之如果唯一磁盤的磁盤節(jié)點崩潰,集群是可以保持運行的贤姆,但不能更改任何東西榆苞。因此建議在集群中設(shè)置兩個磁盤節(jié)點,只要一個可以霞捡,就能正常操作坐漏。
總結(jié)
普通集群模式,并不保證隊列的高可用性碧信。盡管交換機赊琳、綁定這些可以復(fù)制到集群里的任何一個節(jié)點,但是隊列內(nèi)容不會復(fù)制砰碴。雖然該模式解決一項目組節(jié)點壓力躏筏,但隊列節(jié)點宕機直接導(dǎo)致該隊列無法應(yīng)用,只能等待重啟呈枉。所以要想在隊列節(jié)點宕機或故障也能正常應(yīng)用趁尼,就要復(fù)制隊列內(nèi)容到集群里的每個節(jié)點,也就是必須要創(chuàng)建鏡像隊列猖辫。篇幅有限酥泞,RabbitMQ鏡像隊列原理只能后面再分享了,感興趣的朋友可以關(guān)注下住册!