1. 前言
除了計(jì)算機(jī)網(wǎng)絡(luò)、操作系統(tǒng)等基礎(chǔ)知識(shí)的考察,各種流行的中間件也深受面試官的青睞。之前的章節(jié)已經(jīng)對(duì)緩存中間件的代表 Redis 的面試題進(jìn)行了分析,本章節(jié)將介紹常用的消息中間件,即 RabbitMQ 的基礎(chǔ)定義以及使用原因。
2. 消息隊(duì)列使用場(chǎng)景
面試官提問(wèn): 為什么要使用消息隊(duì)列?能說(shuō)說(shuō)消息隊(duì)列解決了什么問(wèn)題?
題目解析:
任何工具都有誕生的背景,例如非關(guān)系型數(shù)據(jù)庫(kù)是為了解決性能以及擴(kuò)展性問(wèn)題產(chǎn)生。
常見(jiàn)的消息隊(duì)列有 RabbitMQ、RocketMQ、Kafka 等,消息隊(duì)列也是針對(duì)特定問(wèn)題有不同的使用場(chǎng)景,可以抽象為異步處理、應(yīng)用解耦、流量削峰三種場(chǎng)景。
2.1 異步處理 & 應(yīng)用解耦
以最常見(jiàn)的在網(wǎng)站注冊(cè)新用戶場(chǎng)景為例,如果經(jīng)過(guò)了基本的業(yè)務(wù)邏輯之后,要通過(guò)短信和郵件的方式驗(yàn)證是否用戶本人注冊(cè),每個(gè)流程的請(qǐng)求響應(yīng)耗時(shí)為 100ms,在同步的方式下總共需要耗時(shí) 300ms。
?
其中發(fā)送驗(yàn)證短信以及發(fā)送驗(yàn)證郵件兩個(gè)步驟并沒(méi)有強(qiáng)制的先后依賴(lài)關(guān)系,所以同步請(qǐng)求的效率相對(duì)較低,使用消息隊(duì)列可以將驗(yàn)證短信和郵件的模塊拆開(kāi),經(jīng)過(guò)消息隊(duì)列中轉(zhuǎn)分發(fā)請(qǐng)求,假設(shè)消息隊(duì)列的讀寫(xiě)時(shí)間為 20ms,總流程的耗時(shí)被優(yōu)化到 220ms。
?
上述異步請(qǐng)求的過(guò)程本質(zhì)上也是應(yīng)用解耦的過(guò)程,最基礎(chǔ)的應(yīng)用架構(gòu)中可以將短信注冊(cè)模塊和郵件注冊(cè)模塊都可以耦合在注冊(cè)業(yè)務(wù)邏輯中,但是如果有其他的服務(wù)也需要使用短信注冊(cè)功能,就只能調(diào)用注冊(cè)業(yè)務(wù)的短信模塊接口。此時(shí),程序的魯棒性相對(duì)較差,當(dāng)注冊(cè)業(yè)務(wù)模塊的服務(wù)器宕機(jī)之后,會(huì)造成所有服務(wù)的短信模塊都不可用,所以需要將短信模塊解耦出來(lái),同理,郵件模塊也需要被拆分為單獨(dú)的服務(wù)。候選人需要注意一點(diǎn),這種拆分本質(zhì)上都是為了應(yīng)用服務(wù)的高可用。
2.2 流量削峰
互聯(lián)網(wǎng)存在很多高并發(fā)場(chǎng)景,例如在 12306 搶購(gòu)春運(yùn)火車(chē)票,或者阿里淘寶的雙十一秒殺活動(dòng),系統(tǒng)服務(wù)在短時(shí)間收到大量的用戶請(qǐng)求,如果數(shù)據(jù)庫(kù)不能抗住相對(duì)日常的 N 倍流量被打垮,會(huì)導(dǎo)致服務(wù)不可用。為了避免這種情況發(fā)生,有熔斷、降級(jí)、以及流量削峰等多種解決方案,消息隊(duì)列是最常見(jiàn)的流量削峰方案。
?
還是以用戶注冊(cè)的例子,例如在雙十一凌晨時(shí)間,大量新用戶通過(guò)活動(dòng)鏈接進(jìn)入了網(wǎng)站的注冊(cè)頁(yè)面,在收到用戶請(qǐng)后后,首先將請(qǐng)求寫(xiě)入消息隊(duì)列,如果請(qǐng)求數(shù)量超過(guò)消息隊(duì)列的容量,那么多余的請(qǐng)求直接放棄并且跳轉(zhuǎn)到錯(cuò)誤頁(yè)面,這也是常用的降級(jí)方案。
業(yè)務(wù)代碼從消息隊(duì)列中拿到用戶請(qǐng)求,再進(jìn)行后續(xù)的業(yè)務(wù)邏輯。消息隊(duì)列在用戶和業(yè)務(wù)邏輯中之間作為中間件模塊,防止大量流量直接打到底層數(shù)據(jù)庫(kù)。
3. 常用消息隊(duì)列
面試官提問(wèn): 常用的消息隊(duì)列有哪些?
題目解析:
最常見(jiàn)的消息隊(duì)列有 ActiveMQ、RabbitMQ、RocketMQ 以及 Kafka,我們一般關(guān)注的是 RabbitMQ 以及 Kafka,我們關(guān)注基本定義以及兩者之間的特性差別。
- RabbitMQ:基于 Erlang 語(yǔ)言開(kāi)發(fā)的消息發(fā)布和訂閱系統(tǒng),基于 AMQP 協(xié)議實(shí)現(xiàn)。AMQP 協(xié)議一般在對(duì)數(shù)據(jù)一致性要求高、對(duì)性能要求較低的場(chǎng)景使用;
- Kafka:LinkedIn 公司開(kāi)源的消息發(fā)布和訂閱系統(tǒng),一般在對(duì)數(shù)據(jù)一致性要求較低、海量數(shù)據(jù)的處理場(chǎng)景中使用。
下面對(duì)比分析下兩種消息隊(duì)列的特性差異。
3.1 吞吐量對(duì)比
- RabbitMQ:?jiǎn)螜C(jī)吞吐量在萬(wàn)級(jí)別,比 Kafka 低一個(gè)數(shù)量級(jí);
- Kafka:?jiǎn)螜C(jī)吞吐量在十萬(wàn)級(jí)別,數(shù)據(jù)的存儲(chǔ)和讀取都是依靠本地硬盤(pán)的順序讀寫(xiě),處理效率高。
3.2 應(yīng)用場(chǎng)景對(duì)比
- RabbitMQ:企業(yè)內(nèi)部微服務(wù),例如內(nèi)部人員管理系統(tǒng)的消息通訊場(chǎng)景。因?yàn)榛?Erlang 開(kāi)發(fā)語(yǔ)言,對(duì)小型企業(yè)來(lái)說(shuō),開(kāi)發(fā)維護(hù)成本相對(duì)較高;
- Kafka:大數(shù)據(jù)系統(tǒng)中常用,例如日志處理以及數(shù)據(jù)實(shí)時(shí)分析場(chǎng)景,目前 Kafka 幾乎是日志采集場(chǎng)景的首選消息隊(duì)列。
4. 小結(jié)
本章節(jié)介紹了消息隊(duì)列的基本使用場(chǎng)景,需要理解消息隊(duì)列的核心是異步處理以及解耦能力。我們對(duì)比了 RabbitMQ 和 Kafka 兩種消息隊(duì)列的特性,在后續(xù)的章節(jié)主要會(huì)對(duì) RabbitMQ 的常見(jiàn)題目進(jìn)行分析。