1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        一文理解為什么需要使用消息隊列

        共 2036字,需瀏覽 5分鐘

         ·

        2021-04-15 12:34

        消息隊列(Message Queue),簡稱為MQ,是一種跨進(jìn)程的通信機(jī)制,用于上下游傳遞消息。常見消息隊列中間件如:Kafka、ActiveMQ、RabbitMQ、RocketMQ等。

        消息隊列引入對系統(tǒng)的優(yōu)勢

        1. 解耦

        在未使用消息隊列的系統(tǒng)中,系統(tǒng)間耦合性太強(qiáng)。如下圖所示的業(yè)務(wù)場景,系統(tǒng)A在代碼中直接調(diào)用系統(tǒng)B和系統(tǒng)C的代碼,如果將來D系統(tǒng)接入或者B系統(tǒng)取消,系統(tǒng)A還需要修改代碼,造成系統(tǒng)風(fēng)險。

        在這個場景中,A系統(tǒng)與其它的系統(tǒng)嚴(yán)重耦合,A系統(tǒng)要考慮各個下游系統(tǒng)如果掛掉的話的失敗重試或兜底策略。

        6872d74ac65b0702a00bc83d06eadfae.webp

        在使用消息隊列后,將下游需要的消息push到消息列隊中,需要消息的系統(tǒng)自己從消息隊列中訂閱;如果某個系統(tǒng)不需要這條數(shù)據(jù)了,就取消對 MQ 消息的訂閱即可,從而系統(tǒng)A不需要做任何修改,也不需要考慮下游消費(fèi)失敗的情況。

        8e1a6967a9626ef4cb62491b5354f809.webp

        通過引入消息隊列的Pub/Sub發(fā)布訂閱消息,A系統(tǒng)就與其它系統(tǒng)徹底解耦。這樣也解決了大系統(tǒng)中多部門或者多人協(xié)作的職責(zé)分離問題,減少事故的發(fā)生。

        2. 異步

        在未使用消息隊列的系統(tǒng)中,一些非必要的業(yè)務(wù)邏輯以同步的方式運(yùn)行,耗費(fèi)大量時間。

        如下圖所示的業(yè)務(wù)場景,A 系統(tǒng)接收一個請求,自身運(yùn)算話費(fèi)30ms,還需要在BCD進(jìn)行運(yùn)算(均需要100ms)。最終請求總延時是 330ms,如果A系統(tǒng)是網(wǎng)關(guān),接收到請求是toc的用戶請求,更高的延時將導(dǎo)致更差的用戶體驗。

        一般互聯(lián)網(wǎng)類的企業(yè),對于用戶直接的操作,一般要求是每個請求都必須在 200 ms 以內(nèi)完成,對用戶幾乎是無感知的。

        e1688eab411965eb937f0f67f1b59c48.webp

        在使用消息隊列后,將系統(tǒng)A的消息寫入消息隊列,非必要的業(yè)務(wù)邏輯BCD以異步的方式運(yùn)行,這樣總耗時就降低到30ms,提升了10倍的響應(yīng)速度。

        9084caf4956de2a26dc60456c34db10c.webp

        使用消息隊列進(jìn)行異步優(yōu)化的時候要熟悉業(yè)務(wù)場景,并不是所有業(yè)務(wù)場景都可以用消息隊列進(jìn)行異步優(yōu)化。

        3. 削峰

        在未使用消息隊列的系統(tǒng)中,系統(tǒng)面對突發(fā)大流量會導(dǎo)致系統(tǒng)崩潰。如下圖所示的業(yè)務(wù)場景,當(dāng)突發(fā)并發(fā)大流量的時候,所有的請求直接懟到數(shù)據(jù)庫,造成數(shù)據(jù)庫連接異常。

        在未使用消息隊列且同時沒有彈性伸縮的系統(tǒng)中,如果突發(fā)大流量,即使下游不是數(shù)據(jù)庫,也會因為消費(fèi)能力不足導(dǎo)致請求大量超時,系統(tǒng)宕機(jī)最終導(dǎo)致分布式系統(tǒng)的雪崩效應(yīng)。

        42ec926934c6b1815596251a9b0ddfa3.webp

        在使用消息隊列后,系統(tǒng)A按照數(shù)據(jù)庫(或下游系統(tǒng))能處理的并發(fā)量,從消息隊列中慢慢拉取消息。在大多數(shù)生產(chǎn)系統(tǒng)的業(yè)務(wù)場景中,短暫的高峰期的消息積壓是允許的。這樣就可以用有限的機(jī)器資源承載高并發(fā)請求。

        如果是下游系統(tǒng)處理能力有限,能增加彈性擴(kuò)容的基礎(chǔ)設(shè)施能力,那當(dāng)然是最好的,但是彈性擴(kuò)容的響應(yīng)速度有限,如果不能應(yīng)對突發(fā)的流量高峰的話,還是推薦使用消息隊列進(jìn)行削峰操作(或者可以的話,使用降級熔斷)。

        25274624de203871778d932781b028f3.webp

        消息隊列引入對系統(tǒng)的劣勢

        雖然消息隊列有上面三種優(yōu)勢,但是并不是盲目使用的。

        系統(tǒng)可用性降低

        系統(tǒng)每增加一個組件,必然導(dǎo)致可用性降低。畢竟沒有一個組件可以保證100%可用性,因此還需要在消息隊列高可用方面花費(fèi)投入。

        系統(tǒng)復(fù)雜性增加

        在使用消息隊列后,會增加很多方面的問題,比如如何保證消息不被重復(fù)消費(fèi)、如何保證消息可靠傳輸、如何保證數(shù)據(jù)一致性問題和如何解決海量消息的積壓故障。因此,需要考慮的東西更多,系統(tǒng)復(fù)雜性增大。

        但上面出現(xiàn)的問題,都是有比較成熟的解決方案的,之后博客會逐個講解。

        什么時候不能使用消息隊列

        最后再講下,什么時候不能使用消息隊列。

        上游請求到來之后,系統(tǒng)A調(diào)用系統(tǒng)B并需要知道B的執(zhí)行結(jié)果。這種業(yè)務(wù)場景下通常不能使用消息隊列,而使用RPC調(diào)用。

        a37e41ca564b10146c8cfc8d145fa702.webp

        這種業(yè)務(wù)場景下使用消息隊列,會導(dǎo)致系統(tǒng)A與系統(tǒng)B的信息割裂。

        74bf114a0bb3acc197a814389208cf9e.webp

        技術(shù)選型

        原本想列出具體消息隊列的優(yōu)劣勢對比,但由于版本不斷更迭,很快這塊內(nèi)容會失去意義,所以只講講選型的原則。首先是要基于團(tuán)隊成員的技術(shù)棧以及部門公司的技術(shù)棧來進(jìn)行選擇,其次是根據(jù)業(yè)務(wù)場景:由于Kafka在大數(shù)據(jù)業(yè)務(wù)中有著無可爭議的優(yōu)勢,所以如果在線業(yè)務(wù)只是需要數(shù)據(jù)流轉(zhuǎn),Kafka完全可以同時兼顧在線業(yè)務(wù)和大數(shù)據(jù)業(yè)務(wù),保證技術(shù)棧單一,便于維護(hù);如果需要復(fù)雜的消息隊列功能,可以根據(jù)版本對應(yīng)的功能,從RabbitMQ和RocketMQ做選型。

        注:

        1. ActiveMQ的社區(qū)活躍已經(jīng)大不如前,而開源項目RabbitMQ的社區(qū)依舊活躍。所以新項目不需要考慮前者。

        2. RocketMQ使用Java開發(fā),RabbitMQ使用Erlang開發(fā)。前者對于廣大Java后端更為友好些,畢竟方便深入源碼。同時作為阿里的開源項目,一段時間內(nèi)的技術(shù)可靠性還是有保證的,如果阿里放棄維護(hù),也會有很多java社區(qū)貢獻(xiàn)者來繼續(xù)完善;后者的社區(qū)活躍與技術(shù)成熟度都要比前者高,且有大量互聯(lián)網(wǎng)公司的成功案例,所以兩個各有利弊,選型的時候需要仔細(xì)思考。

        總結(jié)

        作為后端開發(fā),一定要熟悉消息隊列的優(yōu)缺點,并針對引入消息隊列可能引發(fā)的系統(tǒng)問題作出相應(yīng)的方案設(shè)計,保證系統(tǒng)高可用、高可靠的運(yùn)行,以及保證數(shù)據(jù)的一致性。


        瀏覽 55
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            女人18毛片AAA片水真多 一区二区三区成人 | 日日操日日插 | 欧美成人无码一区二区三区 | 放荡的大乳寡妇k8 | 操逼客 | 色香五月 | 男同桌脱我内裤往里灌水网站 | 日本靠逼视频 | 邻居少妇3中文字幕 | 乱伦视频综合网 |