日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

究竟什么时候该使用MQ?

發(fā)布時間:2025/3/16 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 究竟什么时候该使用MQ? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

任何脫離業(yè)務的組件引入都是耍流氓。引入一個組件,最先該解答的問題是,此組件解決什么問題。

MQ,互聯(lián)網(wǎng)技術(shù)體系中一個常見組件,究竟什么時候不使用MQ,究竟什么時候使用MQ,MQ究竟適合什么場景,是今天要分享的內(nèi)容。

?

MQ是什么?

消息總線(Message Queue),后文稱MQ,是一種跨進程的通信機制,用于上下游傳遞消息。

畫外音:這兩個進程,一般不在同一臺服務器上。

?

在互聯(lián)網(wǎng)架構(gòu)中,MQ經(jīng)常用做“上下游解耦”:

(1)消息發(fā)送方只依賴MQ,不關(guān)注消費方是誰;

(2)消息消費方也只依賴MQ,不關(guān)注發(fā)送方是誰;

畫外音:發(fā)送方與消費方,邏輯上和物理上都不依賴彼此。

什么時候不使用MQ?

當調(diào)用方需要關(guān)心消息執(zhí)行結(jié)果時,通常不使用MQ,而使用RPC調(diào)用。

ret = PassportService::userAuth(name, pass);

switch(ret){

? ? case(YES) : return YesHTML();

? ? case(NO) : return NoHTML();

? ? case(JUMP) : return 304HTML():

? ? default : return 500HTML();

}

?

如上例所示,上游調(diào)用Passport服務,處理結(jié)果不同,業(yè)務會走不同的邏輯處理分支(登錄成功,登錄失敗,執(zhí)行錯誤等),即“處理結(jié)果強依賴”,此時應該使用RPC調(diào)用。

畫外音:絕大部分情況,應該使用RPC。

?

此時如果強行使用MQ呢?

如果強行使用MQ通訊,調(diào)用方不能直接告之用戶登錄成功又或失敗,則要等待另一個MQ通知回調(diào)。這么玩,不但使得編碼復雜,還會引入消息丟失的風險,中間多加入一層,多此一舉。

?

究竟什么時候使用MQ呢?

下面四類典型場景,應該使用MQ。

典型場景一:數(shù)據(jù)驅(qū)動的任務依賴

什么是任務依賴?

舉個栗子,互聯(lián)網(wǎng)公司經(jīng)常在凌晨進行一些數(shù)據(jù)統(tǒng)計任務,這些任務之間有一定的依賴關(guān)系,例如:

(1)task3需要使用task2的輸出作為輸入;

(2)task2需要使用task1的輸出作為輸入;

這樣的話,tast1, task2, task3之間就有任務依賴關(guān)系,必須task1先執(zhí)行,再task2執(zhí)行,載task3執(zhí)行。

對于這類需求,通常怎么實現(xiàn)呢?

常見的玩法是,crontab人工排執(zhí)行時間表

如上圖,手動設(shè)定如下:

(1)task1,0:00執(zhí)行,經(jīng)驗執(zhí)行時間為50分鐘;

(2)task2,1:00執(zhí)行(為task1預留10分鐘buffer),經(jīng)驗執(zhí)行時間也是50分鐘;

(3)task3,2:00執(zhí)行(為task2預留10分鐘buffer);

?

crontab手動排表有什么壞處呢?

(1)如果有一個任務執(zhí)行時間超過了預留buffer的時間,將會得到錯誤的結(jié)果,因為后置任務不清楚前置任務是否執(zhí)行成功,此時要手動重跑任務,還有可能要調(diào)整排班表;

(2)總?cè)蝿盏膱?zhí)行時間很長,總是要預留很多buffer,如果前置任務提前完成,后置任務不會提前開始;

(3)如果一個任務被多個任務依賴,這個任務將會稱為關(guān)鍵路徑,排班表很難體現(xiàn)依賴關(guān)系,容易出錯

(4)如果有一個任務的執(zhí)行時間要調(diào)整,將會有多個任務的執(zhí)行時間要調(diào)整

無論如何,采用“crontab排班表”的方法,各任務嚴重耦合,誰用過誰痛誰知道。

畫外音:用過的,痛過的,請留言。

?

應該如何優(yōu)化呢?

采用MQ解耦。

如上圖,任務之間通過MQ來傳遞“開始”與“結(jié)束”的通知:

(1)task1準時開始,結(jié)束后發(fā)一個“task1 done”的消息;

(2)task2訂閱“task1 done”的消息,收到消息后第一時間啟動執(zhí)行,結(jié)束后發(fā)一個“task2 done”的消息;

(3)task3同理;

?

采用MQ有什么好處呢?

(1)不需要預留buffer,上游任務執(zhí)行完,下游任務總會在第一時間被執(zhí)行;

(2)依賴多個任務,被多個任務依賴都很好處理,只需要訂閱相關(guān)消息即可

(3)有任務執(zhí)行時間變化,下游任務都不需要調(diào)整執(zhí)行時間

?

需要特別說明的是,MQ只用來傳遞上游任務執(zhí)行完成的消息,并不用于傳遞真正的輸入輸出數(shù)據(jù)

?

典型場景二:上游不關(guān)心執(zhí)行結(jié)果

上游需要關(guān)注執(zhí)行結(jié)果時要用“RPC調(diào)用”,上游不關(guān)注執(zhí)行結(jié)果時,使用MQ。

?

舉個栗子,58同城的很多下游需要關(guān)注“用戶發(fā)布帖子”這個事件,比如:

(1)招聘用戶發(fā)布帖子后,招聘業(yè)務要獎勵58豆;

(2)房產(chǎn)用戶發(fā)布帖子后,房產(chǎn)業(yè)務要送2個置頂;

(3)二手用戶發(fā)布帖子后,二手業(yè)務要修改用戶統(tǒng)計數(shù)據(jù);

?

對于這類需求,可以采用什么方式實現(xiàn)呢?

比較無腦的,可以使用RPC調(diào)用來實現(xiàn):

帖子發(fā)布服務執(zhí)行完成之后,調(diào)用下游招聘業(yè)務、房產(chǎn)業(yè)務、二手業(yè)務,來完成消息的通知。

但事實上,這個通知是否正常正確的執(zhí)行,帖子發(fā)布服務根本不關(guān)注。

?

通過RPC來傳遞不需要知道處理結(jié)果的通知,有什么壞處呢?

(1)帖子發(fā)布流程的執(zhí)行時間增加了;

(2)下游服務當機,可能導致帖子發(fā)布服務受影響,上下游邏輯+物理依賴嚴重;

(3)每當增加一個需要知道“帖子發(fā)布成功”信息的下游,修改代碼的是帖子發(fā)布服務;

畫外音:這一點是最惡心的,屬于架構(gòu)設(shè)計中典型的反向依賴。

如何來進行優(yōu)化呢?

采用MQ解耦,代替RPC。

如上圖所示:

(1)帖子發(fā)布成功后,向MQ發(fā)一個消息;

(2)哪個下游關(guān)注“帖子發(fā)布成功”的消息,主動去MQ訂閱;

?

如此一來,有什么好處呢?

(1)上游執(zhí)行時間短;

(2)上下游邏輯+物理解耦,除了與MQ有物理連接,模塊之間都不相互依賴;

(3)新增一個下游消息關(guān)注方,上游不需要修改任何代碼;

?

典型場景三:上游關(guān)注執(zhí)行結(jié)果,但執(zhí)行時間很長

有時候上游需要關(guān)注執(zhí)行結(jié)果,但執(zhí)行結(jié)果時間很長(典型的是調(diào)用離線處理,或者跨公網(wǎng)調(diào)用),也經(jīng)常使用回調(diào)網(wǎng)關(guān)+MQ來解耦。

?

舉個栗子,微信支付,跨公網(wǎng)調(diào)用微信的接口,執(zhí)行時間會比較長,但調(diào)用方又非常關(guān)注執(zhí)行結(jié)果,此時一般怎么玩呢?

一般采用“回調(diào)網(wǎng)關(guān)+MQ”方案來解耦:

(1)調(diào)用方直接跨公網(wǎng)調(diào)用微信接口;

(2)微信返回調(diào)用成功,此時并不代表返回成功;

(3)微信執(zhí)行完成后,回調(diào)統(tǒng)一網(wǎng)關(guān);

(4)網(wǎng)關(guān)將返回結(jié)果通知MQ;

(5)請求方收到結(jié)果通知;

?

這里需要注意的是,不應該由回調(diào)網(wǎng)關(guān)來RPC通知上游來通知結(jié)果,如果是這樣的話,每次新增調(diào)用方,回調(diào)網(wǎng)關(guān)都需要修改代碼,仍然會反向依賴,使用回調(diào)網(wǎng)關(guān)+MQ的方案,新增任何對微信支付的調(diào)用,都不需要修改代碼。

?

結(jié)尾總結(jié)

MQ是一個互聯(lián)網(wǎng)架構(gòu)中常見的解耦利器。

什么時候不使用MQ?

上游實時關(guān)注執(zhí)行結(jié)果,通常采用RPC。

?

什么時候使用MQ?

(1)數(shù)據(jù)驅(qū)動的任務依賴;

(2)上游不關(guān)心多下游執(zhí)行結(jié)果;

(3)異步返回執(zhí)行時間長;

知其然,知其所以然,希望大家有收獲。

有道無術(shù),術(shù)可成;有術(shù)無道,止于術(shù)

歡迎大家關(guān)注Java之道公眾號

好文章,我在看??

新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎!定制產(chǎn)品紅包拿不停!

總結(jié)

以上是生活随笔為你收集整理的究竟什么时候该使用MQ?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。