這兩天在針對(duì)項(xiàng)目過(guò)程使用的RabbitMQ得學(xué)習(xí)文檔整理的過(guò)程中,發(fā)現(xiàn)還遺漏了RabbitMQ的就集群原理的系統(tǒng)的分析的文檔,這個(gè)就比較尷尬了,正好最近在整理RabbitMQ的集群的搭建,那我們今天就聊聊RabbitMQ的集群的相關(guān)原理
RabbitMQ的優(yōu)缺點(diǎn)
在正式的聊聊集群的原理之前,我們先簡(jiǎn)單了解下RabbitMQ的優(yōu)缺點(diǎn),然后為什么要使用RabbitMQ的集群模式,他能為我們解決那些問(wèn)題,各種不同的集群模式有什么區(qū)別,又有什么優(yōu)缺點(diǎn);
RabbitMQ的優(yōu)缺點(diǎn)
RabbitMQ的優(yōu)點(diǎn),我在Centos7下RabbitMQ的搭建其實(shí)已經(jīng)介紹過(guò)了,無(wú)外乎三大點(diǎn):解耦、削峰、異步通訊等,我們這里簡(jiǎn)單提下,但是相對(duì)于優(yōu)點(diǎn)來(lái)說(shuō),RabbitMQ同樣也有缺點(diǎn):
- 增加了系統(tǒng)應(yīng)用的復(fù)雜性
- RabbitMQ服務(wù)如果出現(xiàn)問(wèn)題,則整個(gè)服務(wù)將會(huì)癱瘓
- 新增了很多異常情況的處理, 比如消息丟失、消息消費(fèi)失敗, 消息重復(fù)消費(fèi)等
- RabbitMQ服務(wù)在高并發(fā)情況下很容易出現(xiàn)性能瓶頸,進(jìn)而影響整個(gè)系統(tǒng)的運(yùn)行
其中1和3的問(wèn)題都可以通過(guò)代碼和配置來(lái)解決,但是問(wèn)題2和4就不好解決了,為了解決上面的問(wèn)題,就出現(xiàn)了RabbitMQ服務(wù)的集群
RabbitMQ兩種集群
普通集群
什么是普通集群呢? 就是在多個(gè)聯(lián)通的服務(wù)器上安裝不同的RabbitMQ的服務(wù),這些服務(wù)器上的RabbitMQ服務(wù)組成一個(gè)個(gè)節(jié)點(diǎn),通過(guò)RabbitMQ內(nèi)部提供的命令或者配置來(lái)構(gòu)建集群,形成了RabbitMQ的普通集群模式

- 當(dāng)用戶向服務(wù)注冊(cè)一個(gè)隊(duì)列,該隊(duì)列會(huì)隨機(jī)保存到某一個(gè)服務(wù)節(jié)點(diǎn)上,然后將對(duì)應(yīng)的元數(shù)據(jù)同步到各個(gè)不同的服務(wù)節(jié)點(diǎn)上
- RabbitMQ的普通集群模式中,每個(gè)RabbitMQ都保存有相同的元數(shù)據(jù)
- 用戶只需要鏈接到任一一個(gè)服務(wù)節(jié)點(diǎn)中,就可以監(jiān)聽(tīng)消費(fèi)到對(duì)應(yīng)隊(duì)列上的消息數(shù)據(jù)
- 但是RabbitMQ的實(shí)際數(shù)據(jù)卻不是保存在每個(gè)RabbitMQ的服務(wù)節(jié)點(diǎn)中,這就意味著用戶可能聯(lián)系的是RabbitMQ服務(wù)節(jié)點(diǎn)C,但是C上并沒(méi)有對(duì)應(yīng)的實(shí)際數(shù)據(jù),也就是說(shuō)RabbitMQ服務(wù)節(jié)點(diǎn)C,并不能提供消息供用戶來(lái)消費(fèi),那么RabbitMQ的普通集群模式如何解決這個(gè)問(wèn)題呢?
- RabbitMQ服務(wù)節(jié)點(diǎn)C發(fā)現(xiàn)自己本服務(wù)節(jié)點(diǎn)并沒(méi)有對(duì)應(yīng)的實(shí)際數(shù)據(jù)后,因?yàn)槊總€(gè)服務(wù)節(jié)點(diǎn)上都會(huì)保存相同的元數(shù)據(jù),所以服務(wù)節(jié)點(diǎn)C會(huì)根據(jù)元數(shù)據(jù),向服務(wù)節(jié)點(diǎn)B(該服務(wù)節(jié)點(diǎn)上有實(shí)際數(shù)據(jù)可供消費(fèi))請(qǐng)求實(shí)際數(shù)據(jù),然后提供給用戶進(jìn)行消費(fèi)
- 這樣給用戶的感覺(jué)就是,在RabbitMQ的普通集群模式中,用戶連接任一服務(wù)節(jié)點(diǎn)都可以消費(fèi)到消息
-普通集群模式的優(yōu)點(diǎn):提高消費(fèi)的吞吐量
普通集群模式的原理比較簡(jiǎn)單,但是并不能真正意義上的實(shí)現(xiàn)高可用,他也存在以下的以下缺點(diǎn):
- 為了請(qǐng)求RabbitMQ的實(shí)際數(shù)據(jù)以提供給用戶,可能會(huì)在RabbitMQ內(nèi)部服務(wù)節(jié)點(diǎn)之間進(jìn)行頻繁的進(jìn)行數(shù)據(jù)交互,這樣的交互比較耗費(fèi)資源
- 當(dāng)其中一個(gè)RabbitMQ的服務(wù)節(jié)點(diǎn)宕機(jī)了,那么該節(jié)點(diǎn)上的實(shí)際數(shù)據(jù)就會(huì)丟失,用戶再次請(qǐng)求時(shí),就會(huì)請(qǐng)求不到數(shù)據(jù),系統(tǒng)的功能就會(huì)出現(xiàn)異常
那么該怎么解決上述的問(wèn)題呢?
鏡像集群模式
為了解決上面普通模式的兩個(gè)顯著的缺點(diǎn),RabbitMQ官方提供另外一種集群模式:鏡像集群模式

鏡像集群模式和普通集群模式大體是一樣的,不一樣的是:
- 生產(chǎn)者向任一服務(wù)節(jié)點(diǎn)注冊(cè)隊(duì)列,該隊(duì)列相關(guān)信息會(huì)同步到其他節(jié)點(diǎn)上
- 任一消費(fèi)者向任一節(jié)點(diǎn)請(qǐng)求消費(fèi),可以直接獲取到消費(fèi)的消息,因?yàn)槊總€(gè)節(jié)點(diǎn)上都有相同的實(shí)際數(shù)據(jù)
- 任一節(jié)點(diǎn)宕機(jī),不影響消息在其他節(jié)點(diǎn)上進(jìn)行消費(fèi)
鏡像集群模式是怎么開(kāi)啟的呢?這里簡(jiǎn)單說(shuō)下,在普通集群模式的基礎(chǔ)上,我們可以通過(guò)web控制端來(lái)配置數(shù)據(jù)的同步策略,可以配置同步所有的節(jié)點(diǎn),也可以配置同步到指定數(shù)量的服務(wù)節(jié)點(diǎn)
雖然鏡像集群模式能夠解決普通集群模式的缺點(diǎn),當(dāng)任一節(jié)點(diǎn)宕機(jī)了,不能正常提供服務(wù)了,也不影響該消息的正常消費(fèi),但是其本身也有相應(yīng)的缺點(diǎn):
- 性能開(kāi)銷(xiāo)非常大,因?yàn)橐较⒌綄?duì)應(yīng)的節(jié)點(diǎn),這個(gè)會(huì)造成網(wǎng)絡(luò)之間的數(shù)據(jù)量的頻繁交互,對(duì)于網(wǎng)絡(luò)帶寬的消耗和壓力都是比較重的
- 沒(méi)有擴(kuò)展可言,rabbitMQ是集群,不是分布式的,所以當(dāng)某個(gè)Queue負(fù)載過(guò)重,我們并不能通過(guò)新增節(jié)點(diǎn)來(lái)緩解壓力,因?yàn)樗怨?jié)點(diǎn)上的數(shù)據(jù)都是相同的,這樣就沒(méi)辦法進(jìn)行擴(kuò)展了
對(duì)于鏡像集群而言,當(dāng)某個(gè)queue負(fù)載過(guò)重,可能會(huì)導(dǎo)致集群雪崩,那么如何來(lái)減少集群雪崩呢?我們可以通過(guò)HA的同步策略來(lái)實(shí)現(xiàn)
HA的同步策略如下:
| HA-mode | HA-params | 說(shuō)明 |
|---|---|---|
| all | 空 | 鏡像隊(duì)列將會(huì)在整個(gè)集群中復(fù)制。當(dāng)一個(gè)新的節(jié)點(diǎn)加入后,也會(huì)在這個(gè)節(jié)點(diǎn)上復(fù)制一份。 |
| exactly | count | 鏡像隊(duì)列將會(huì)在集群上復(fù)制count份。如果集群數(shù)量少于count時(shí)候,隊(duì)列會(huì)復(fù)制到所有節(jié)點(diǎn)上。 如果大于Count集群,有一個(gè)節(jié)點(diǎn)crash后,新進(jìn)入節(jié)點(diǎn)也不會(huì)做新的鏡像。(可以阻止集群雪崩) |
| nodes | node name | 鏡像隊(duì)列會(huì)在node name中復(fù)制。如果這個(gè)名稱(chēng)不是集群中的一個(gè),這不會(huì)觸發(fā)錯(cuò)誤。 如果在這個(gè)node list中沒(méi)有一個(gè)節(jié)點(diǎn)在線,那么這個(gè)queue會(huì)被聲明在client連接的節(jié)點(diǎn)。 |