由于業(yè)務(wù)的需要用到隊(duì)列,并保證隊(duì)列的高可用性,我們選擇了RabbitMQ的鏡像集群模式。這種集群模式在隊(duì)列節(jié)點(diǎn)宕機(jī)或故障時(shí)也能正常使用,因?yàn)樗С謴?fù)制隊(duì)列內(nèi)容到集群里的每個(gè)節(jié)點(diǎn)。
OK,關(guān)于RabbitMQ的基本知識(shí)就不在這里普及了,直接看我們總結(jié)的需要關(guān)注的幾個(gè)可用性測(cè)試點(diǎn):
1. 在集群工作中如果一個(gè)或幾個(gè)節(jié)點(diǎn)宕機(jī)會(huì)不會(huì)導(dǎo)致隊(duì)列數(shù)據(jù)的丟失?
2. DISC的節(jié)點(diǎn)可以在其宕機(jī)重啟后保存隊(duì)列數(shù)據(jù)嗎?
3. RAM和DISC模式的速度差有多大?有沒有必要所有節(jié)點(diǎn)都采用DISC模式?
4. 影響上游生產(chǎn)者和下游消費(fèi)者的發(fā)送和接收的情況會(huì)有哪些?何時(shí)會(huì)導(dǎo)致連接問題?
有了以上的問題,我們就可以部署我們的測(cè)試了,首先當(dāng)然是集群環(huán)境搭建,這里不會(huì)花篇幅在搭建上,網(wǎng)上的例子很多,比如:環(huán)境搭建?
我們測(cè)試用會(huì)有三臺(tái)機(jī)器,1臺(tái)為DISC模式(磁盤),另外兩臺(tái)為RAM模式(內(nèi)存)。在完成了環(huán)境搭建后,我們的集群應(yīng)該滿足下列的條件:
a. 在3臺(tái)物理機(jī)的控制臺(tái)分別輸入rabbitmqctl cluster_status后:

可以看到三個(gè)控制臺(tái)的輸出都是差不多的,而且一臺(tái)為disc模式:rabbit@7-2;另外兩臺(tái)是ram模式:rabbit@7-3和rabbit@7-15
b. 分別打開三個(gè)RabbitMQ的網(wǎng)頁(yè)管理端并創(chuàng)建和配置vHost,Queue,Policy等(具體步驟省略,可參考上面環(huán)境配置網(wǎng)頁(yè)),展示為:
Overview頁(yè)面(顯示的集群中各節(jié)點(diǎn)的狀態(tài)都是正確的)

Queue頁(yè)面(我們可以看到在Node項(xiàng)下有一個(gè)“+2”,表示集群還有兩個(gè)節(jié)點(diǎn)和本節(jié)點(diǎn)是鏡像同步模式)

滿足了上面的條件,我們就可以開始測(cè)試集群了。
1. 在集群工作中如果一個(gè)或幾個(gè)節(jié)點(diǎn)宕機(jī)會(huì)不會(huì)導(dǎo)致隊(duì)列數(shù)據(jù)的丟失?
我們可以先往某一個(gè)隊(duì)列里寫1000個(gè)數(shù)據(jù):

然后查看3個(gè)RabbitMQ的網(wǎng)頁(yè)管理端的Queue頁(yè)面,Messages里面Ready的數(shù)據(jù)為1000個(gè):

通過查詢3個(gè)RabbitMQ的網(wǎng)頁(yè)管理端的Queue頁(yè)面,可以看到3個(gè)端中Queue頁(yè)面的數(shù)據(jù)都是一樣的(如上圖),全部都是有1000個(gè)數(shù)據(jù),單從頁(yè)面上看,幾個(gè)節(jié)點(diǎn)應(yīng)該是完成了數(shù)據(jù)的鏡像復(fù)制,就是說(shuō)現(xiàn)在任何一個(gè)節(jié)點(diǎn)或者多個(gè)節(jié)點(diǎn)宕機(jī),只要還剩一個(gè)節(jié)點(diǎn)存活,我們的數(shù)據(jù)就還是可以被消費(fèi)了,那好,我們就關(guān)掉兩臺(tái)節(jié)點(diǎn):rabbit@7-3和rabbit@7-15
ps:關(guān)掉節(jié)點(diǎn)的語(yǔ)句是 rabbitmqctl stop_app
兩個(gè)節(jié)點(diǎn)關(guān)閉后么可以看到網(wǎng)頁(yè)管理端的Queue頁(yè)面的變化:

可以看到,Node里面的“+2”標(biāo)志消失了,代表現(xiàn)在集群中只有一個(gè)節(jié)點(diǎn)rabbit@7-2了;從圖上也可以看到,Messages里面的消息數(shù)量還是1000沒有變,我們現(xiàn)在就寫個(gè)消費(fèi)者獲取下,看看是不是能夠獲得這1000個(gè)消息數(shù)據(jù)。


通過試驗(yàn),我們發(fā)現(xiàn)發(fā)送的1000個(gè)消息都可以收到,所以,在集群工作中如果一個(gè)或幾個(gè)節(jié)點(diǎn)宕機(jī)是不會(huì)導(dǎo)致隊(duì)列數(shù)據(jù)的丟失的。
2. DISC的節(jié)點(diǎn)可以在其宕機(jī)重啟后保存隊(duì)列數(shù)據(jù)嗎?
我們搭建的集群的DISC節(jié)點(diǎn)是rabbit@7-2,那我們就針對(duì)它進(jìn)行這個(gè)測(cè)試。
還是先發(fā)送1000個(gè)消息給集群:

確認(rèn)將三個(gè)節(jié)點(diǎn)全部掛掉(沒有running nodes):

確認(rèn)后將三個(gè)節(jié)點(diǎn)打開并通過網(wǎng)頁(yè)管理端的Queue頁(yè)面查看:

可以看到,消息還是1000個(gè),沒有丟。但是有個(gè)細(xì)節(jié),Node下面有了些變化。有了一個(gè)紅色的“+2”出現(xiàn),它的意思是現(xiàn)在集群中有兩個(gè)節(jié)點(diǎn)(rabbit@7-3和rabbit@7-15)還沒有實(shí)現(xiàn)鏡像同步,因?yàn)橹坝?000個(gè)消息它們兩個(gè)節(jié)點(diǎn)不知道(因?yàn)槭荝AM的,重啟后就消失了)。但是我們可以從rabbit@7-3和rabbit@7-15獲得這1000個(gè)消息嗎?試試看的結(jié)果是:可以!

消息都消費(fèi)完后,網(wǎng)頁(yè)管理端的Queue頁(yè)面變?yōu)榱耍?/p>

3. RAM和DISC模式的速度差有多大?有沒有必要所有節(jié)點(diǎn)都采用DISC模式?
為了測(cè)試這個(gè),我們單獨(dú)選出來(lái)了兩個(gè)Node進(jìn)行點(diǎn)對(duì)點(diǎn)的測(cè)試:rabbit@7-3(RAM)和rabbit@7-2(RAM),并采用1000/s的頻率發(fā)送消息,計(jì)算速度的方式為:AVERAGE(消費(fèi)者接收到消息的時(shí)間 - 生產(chǎn)者發(fā)送消息的時(shí)間)
將生產(chǎn)者和消費(fèi)者程序中的Node節(jié)點(diǎn)統(tǒng)一變?yōu)閞abbit@7-2的IP后,先打開消費(fèi)者,再打開生產(chǎn)者,此種情況下計(jì)算出的消息速度為:8.33ms
將生產(chǎn)者和消費(fèi)者程序中的Node節(jié)點(diǎn)統(tǒng)一變?yōu)閞abbit@7-3的IP后,先打開消費(fèi)者,再打開生產(chǎn)者,此種情況下計(jì)算出的消息速度為:3.36ms
可以看到,RAM節(jié)點(diǎn)的消息速度比DISC的速度快2.5~3倍。而且隨著發(fā)送頻率的增加,這個(gè)速度差距會(huì)越來(lái)越大。所以,在實(shí)際應(yīng)用中,如果對(duì)消息的速度要求很高,建議還是以RAM節(jié)點(diǎn)為主。
4. 影響上游生產(chǎn)者和下游消費(fèi)者的發(fā)送和接收的情況會(huì)有哪些?何時(shí)會(huì)導(dǎo)致連接問題?
其實(shí),影響生產(chǎn)者和消費(fèi)者發(fā)送和接收消息的情況很多,根據(jù)我們之前做的測(cè)試,RabbitMQ集群中只要不是全部節(jié)點(diǎn)全掛掉,我們就不會(huì)停止傳輸消息。但這并不意味著你的系統(tǒng)就完全的高枕無(wú)憂了,因?yàn)槟闳绾魏蚏abbitMQ集群連接是個(gè)關(guān)鍵問題,比如如果在程序中寫死了連接的節(jié)點(diǎn)IP,這個(gè)節(jié)點(diǎn)掛掉的話那就是連不上了,集群也無(wú)能為力。
目前應(yīng)該有兩個(gè)可行的方法使集群起到作用:
1. 在集群前端加一個(gè)LB,統(tǒng)一為一個(gè)IP和端口,負(fù)載均衡和節(jié)點(diǎn)輪詢?nèi)冀唤o它就好了,但是要注意DISC的分配問題,不使用或優(yōu)先級(jí)降低。
2. 自己的程序?qū)崿F(xiàn)節(jié)點(diǎn)輪詢。這個(gè)需要程序人員自己寫了,來(lái)實(shí)現(xiàn)上述LB的功能。