消息服務(wù):MQ使用場景與選型對比
在前面的文章中,我們實現(xiàn)了用戶微服務(wù)、商品微服務(wù)和訂單微服務(wù)之間的遠(yuǎn)程調(diào)用,并且實現(xiàn)了服務(wù)調(diào)用的負(fù)載均衡。也基于阿里開源的Sentinel實現(xiàn)了服務(wù)的限流與容錯,并詳細(xì)介紹了Sentinel的核心技術(shù)與配置規(guī)則。
簡單介紹了服務(wù)網(wǎng)關(guān),并對SpringCloud Gateway的核心架構(gòu)進(jìn)行了簡要說明,也在項目中整合了SpringCloud
Gateway網(wǎng)關(guān)實現(xiàn)了通過網(wǎng)關(guān)訪問后端微服務(wù),同時,也基于SpringCloud Gateway整合Sentinel實現(xiàn)了網(wǎng)關(guān)的限流功能,詳細(xì)介紹了SpringCloud Gateway網(wǎng)關(guān)的核心技術(shù)。
在鏈路追蹤章節(jié),我們開始簡單介紹了分布式鏈路追蹤技術(shù)與解決方案,隨后在項目中整合Sleuth實現(xiàn)了鏈路追蹤,并使用Sleuth整合ZipKin實現(xiàn)了分布式鏈路追蹤的可視化 。
今天,我們正式進(jìn)入消息服務(wù)章節(jié),首先,我們來簡單的聊聊MQ的使用場景,引入MQ后的注意事項以及MQ的選型對比。
本章總覽
MQ的使用場景
MQ的英文全稱是Message Queue,翻譯成中文就是消息隊列,隊列實現(xiàn)了先進(jìn)先出(FIFO)的消息模型。通過消息隊列,我們可以實現(xiàn)多個進(jìn)程之間的通信,例如,可以實現(xiàn)多個微服務(wù)之間的消息通信。MQ的最簡模型就是生產(chǎn)者生產(chǎn)消息,將消息發(fā)送到MQ,消息消費(fèi)者訂閱MQ,消費(fèi)消息。
MQ的使用場景通常包含:異步解耦、流量削峰。
異步解耦
關(guān)于異步的場景,我們這里舉一個用戶下單成功后,向用戶發(fā)送通知消息,為用戶增加積分和優(yōu)惠券的場景。
同步耦合場景分析
如果是同步調(diào)用的場景,則具體業(yè)務(wù)為:當(dāng)用戶提交訂單成功后,訂單系統(tǒng)會調(diào)用通知系統(tǒng)為用戶發(fā)送消息通知,告知用戶下單成功,訂單系統(tǒng)調(diào)用積分系統(tǒng)為用戶增加積分,訂單系統(tǒng)調(diào)用優(yōu)惠券系統(tǒng)為用戶增加優(yōu)惠券。整個調(diào)用流程如下所示。
通過上圖的分析,可以看到,用戶調(diào)用訂單系統(tǒng)下單時,總共會經(jīng)過8個步驟。并且每個步驟都是緊密耦合在一起串行執(zhí)行,如下所示。
此時,訂單系統(tǒng)、通知系統(tǒng)、積分系統(tǒng)和優(yōu)惠券系統(tǒng)是緊密耦合在一起的,訂單系統(tǒng)下單、通知系統(tǒng)發(fā)通知、積分系統(tǒng)發(fā)積分和優(yōu)惠券系統(tǒng)發(fā)優(yōu)惠券,四個任務(wù)全部完成后,才會給用戶返回提交訂單的結(jié)果信息。
用戶提交訂單花費(fèi)的總時間為調(diào)用訂單系統(tǒng)下單的時間+訂單系統(tǒng)調(diào)用通知系統(tǒng)發(fā)送通知的時間+訂單系統(tǒng)調(diào)用積分系統(tǒng)發(fā)放積分的時間+訂單系統(tǒng)調(diào)用優(yōu)惠券系統(tǒng)發(fā)放優(yōu)惠券的時間。
注意:這里為了更好的說明系統(tǒng)之間串行執(zhí)行的問題,忽略了網(wǎng)絡(luò)的延遲時間。
這種串行化的系統(tǒng)執(zhí)行方式,在高并發(fā)、大流量場景下是不可取的。另外,如果其中一個系統(tǒng)異?;蛘咤礄C(jī),勢必會影響到訂單系統(tǒng)的可用性。在系統(tǒng)維護(hù)上,只要任意一個系統(tǒng)的接口發(fā)生變動,訂單系統(tǒng)的邏輯也要跟著發(fā)生變動。
異步解耦場景分析
既然在高并發(fā)、大流量場景下使用訂單系統(tǒng)直接串行調(diào)用通知系統(tǒng)、積分系統(tǒng)和優(yōu)惠券系統(tǒng)的方式不可取。那我們是否能夠使用異步解耦的方式呢。
其實,在用戶提交訂單的場景中,用戶最關(guān)心的是自己的訂單是否提交成功,由于下單時,訂單系統(tǒng)會直接返回是否下單成功的提示。
對于通知、積分和優(yōu)惠券可以以異步的方式延后一小段時間執(zhí)行。并且通知系統(tǒng)、積分系統(tǒng)和優(yōu)惠券系統(tǒng)之間不存在必然的業(yè)務(wù)關(guān)聯(lián)邏輯,它們之間可以以并行的方式執(zhí)行。
所以,可以使用MQ將訂單系統(tǒng)與通知系統(tǒng)、積分系統(tǒng)和優(yōu)惠券系統(tǒng)進(jìn)行解耦,用戶調(diào)用訂單系統(tǒng)的接口下單時,訂單系統(tǒng)向數(shù)據(jù)庫寫入訂單數(shù)據(jù)后,向MQ寫入消息,就可以直接返回給用戶下單成功的提示,此時通知系統(tǒng)、積分系統(tǒng)和優(yōu)惠券系統(tǒng)都訂閱MQ中的消息,收到消息后各自執(zhí)行自身的業(yè)務(wù)邏輯即可。
當(dāng)引入MQ進(jìn)行異步解耦之后,用戶調(diào)用訂單系統(tǒng)的接口下單,訂單系統(tǒng)執(zhí)行完業(yè)務(wù)邏輯將訂單數(shù)據(jù)入口,會向MQ發(fā)送一條消息,隨后便直接返回用戶下單成功的提示。通知系統(tǒng)、積分系統(tǒng)和優(yōu)惠券系統(tǒng)會同時訂閱MQ中的消息,當(dāng)收到消息時,它們各自會執(zhí)行自身的業(yè)務(wù)邏輯,并且它們是以并行的方式執(zhí)行各自的業(yè)務(wù)邏輯。
從執(zhí)行的時間線上可以看出,當(dāng)引入MQ進(jìn)行異步解耦之后,通知系統(tǒng)、積分系統(tǒng)、優(yōu)惠券系統(tǒng)和訂單系統(tǒng)回復(fù)響應(yīng)都是并行執(zhí)行的,大大提高系統(tǒng)的執(zhí)行性能。
并且解耦后,任意一個系統(tǒng)異常或者宕機(jī),都不會影響到訂單系統(tǒng)的可用性。只要訂單系統(tǒng)與其他系統(tǒng)提前約定好發(fā)送的消息格式和消息內(nèi)容,后續(xù)任意一個系統(tǒng)的業(yè)務(wù)邏輯變動,幾乎都不會影響到訂單系統(tǒng)的邏輯。
流量削峰
MQ在高并發(fā)、大流量的場景下可以用作削峰填谷的利器,例如,12306的春運(yùn)搶票場景、高并發(fā)秒殺場景、雙十一和618的大促場景等。
在高并發(fā)、大流量業(yè)務(wù)場景下,瞬間會有大量用戶的請求涌入系統(tǒng),如果不對這些流量做處理的話,直接讓這些流量進(jìn)入下游系統(tǒng),則很可能由于下游系統(tǒng)無法支撐如此高的并發(fā)而導(dǎo)致系統(tǒng)崩潰或宕機(jī)。為了解決這些問題,可以引入MQ進(jìn)行流量的削峰填谷。
將流量發(fā)送到MQ中后,下游系統(tǒng)根據(jù)自身的處理能力進(jìn)行消費(fèi)即可。保證了下游系統(tǒng)的高可用性。
引入MQ后的注意事項
引入MQ最大的優(yōu)點就是異步解耦和流量削峰,但是引入MQ后也有很多需要注意的事項和問題,主要包括:系統(tǒng)的整體可用性降低、系統(tǒng)的復(fù)雜度變高、引入了消息一致性的問題。
系統(tǒng)的整體可用性降低
在對一個系統(tǒng)進(jìn)行架構(gòu)設(shè)計時,引入的外部依賴越多,系統(tǒng)的穩(wěn)定性和可用性就會降低。系統(tǒng)中引入了MQ,部分業(yè)務(wù)就會出現(xiàn)強(qiáng)依賴MQ的現(xiàn)象,此時,如果MQ宕機(jī),則部分業(yè)務(wù)就會變得不可用。所以,引入MQ時,我們就要考慮如何實現(xiàn)MQ的高可用。
系統(tǒng)的復(fù)雜度變高
引入MQ后,會使之前的同步接口調(diào)用變成通過MQ的異步調(diào)用,在實際的開發(fā)過程中,異步調(diào)用會比同步調(diào)用復(fù)雜的多。并且異步調(diào)用出現(xiàn)問題后,重現(xiàn)問題,定位問題和解決問題都會比同步調(diào)用復(fù)雜的多。
并且引入MQ后,還要考慮如何保證消息的順序等問題。
消息一致性問題
引入MQ后,不得不考慮的一個問題就是消息的一致性問題。這期間就要考慮如何保證消息不丟失,消息冪等和消息數(shù)據(jù)處理的冪等性問題。
MQ選型對比
目前,在行業(yè)內(nèi)使用的比較多的MQ包含RabbitMQ、Kafka和RocketMQ。這里,我將三者的對比簡單整理了個表格,如下所示。
消息中間件(MQ) | 優(yōu)點 | 缺點 | 使用場景 |
RabbitMQ | 功能全面、消息的可靠性比較高 | 吞吐量低,消息大量積累會影響性能,使用的開發(fā)語言是erlang,不好定制功能。 | 規(guī)模不大的場景 |
Kafka | 吞吐量最高,性能最好,集群模式下高可用 | 功能上比較單一,會丟失部分?jǐn)?shù)據(jù) | 日志分析,大數(shù)據(jù)場景 |
RocketMQ | 吞吐量高,性能高,可用性高,功能全面。使用Java語言開發(fā),容易定制功能。 | 開源版不如阿里云上版,文檔比較簡單。 | 幾乎支持所有場景,包含大數(shù)據(jù)場景和業(yè)務(wù)場景。 |