<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          消息隊列的七種經(jīng)典應用場景

          共 5444字,需瀏覽 11分鐘

           ·

          2024-04-02 16:03

          在筆者心中,消息隊列緩存分庫分表是高并發(fā)解決方案三劍客。

          在職業(yè)生涯中,筆者曾經(jīng)使用過 ActiveMQ 、RabbitMQ 、Kafka 、RocketMQ 這些知名的消息隊列 。

          這篇文章,筆者結(jié)合自己的真實經(jīng)歷,和大家分享消息隊列的七種經(jīng)典應用場景。

          1 異步&解耦

          筆者曾經(jīng)負責某電商公司的用戶服務,該服務提供用戶注冊,查詢,修改等基礎(chǔ)功能。用戶注冊成功之后,需要給用戶發(fā)送短信。

          圖中,新增用戶發(fā)送短信都揉在用戶中心服務里,這種方式缺點非常明顯:

          1. 假如短信渠道接口不穩(wěn)定,發(fā)送短信發(fā)生超時,用戶注冊接口耗時很大,影響前端用戶體驗;

          2. 短信渠道接口發(fā)生變化,用戶中心代碼就必須修改了。但用戶中心是核心系統(tǒng)。每次上線都必要謹小慎微。這種感覺很別扭,非核心功能影響到核心系統(tǒng)了。

          為了解決這個問題,筆者采用了消息隊列進行了重構(gòu)。

          • 異步:用戶中心服務保存用戶信息成功后,發(fā)送一條消息到消息隊列 ,立即將結(jié)果返回給前端,這樣能避免總耗時比較長,從而影響用戶的體驗的問題。

          • 解耦:任務服務收到消息調(diào)用短信服務發(fā)送短信,將核心服務與非核心功能剝離,顯著的降低了系統(tǒng)間的耦合度。

          如果想學Java項目的,強烈推薦我的??項目消息推送平臺Austin10K+ stars),可以用作畢業(yè)設計,可以用作校招,可以看看生產(chǎn)環(huán)境是怎么推送消息的。 

          倉庫地址(可點擊閱讀原文跳轉(zhuǎn)):https://gitee.com/zhongfucheng/austin

          2 消峰

          高并發(fā)場景下,面對突然出現(xiàn)的請求峰值,非常容易導致系統(tǒng)變得不穩(wěn)定,比如大量請求訪問數(shù)據(jù)庫,會對數(shù)據(jù)庫造成極大的壓力,或者系統(tǒng)的資源 CPU 、IO 出現(xiàn)瓶頸。

          筆者曾服務于神州專車訂單團隊,在訂單的載客生命周期里,訂單的修改操作先修改訂單緩存,然后發(fā)送消息到 MetaQ ,訂單落盤服務消費消息,并判斷訂單信息是否正常(比如有無亂序),若訂單數(shù)據(jù)無誤,則存儲到數(shù)據(jù)庫中。

          當面對請求峰值時,由于消費者的并發(fā)度在一個閾值范圍內(nèi),同時消費速度相對均勻,因此不會對數(shù)據(jù)庫造成太大的影響,同時真正面對前端的訂單系統(tǒng)生產(chǎn)者也會變得更穩(wěn)定。

          3 消息總線

          所謂總線,就是像主板里的數(shù)據(jù)總線一樣, 具有數(shù)據(jù)的傳遞和交互能力,各方不直接通信,使用總線作為標準通信接口

          筆者曾經(jīng)服務于某彩票公司訂單團隊,在彩票訂單的生命周期里,經(jīng)過創(chuàng)建,拆分子訂單,出票,算獎等諸多環(huán)節(jié)。每一個環(huán)節(jié)都需要不同的服務處理,每個系統(tǒng)都有自己獨立的表,業(yè)務功能也相對獨立。假如每個應用都去修改訂單主表的信息,那就會相當混亂了。

          因此,公司的架構(gòu)師設計了調(diào)度中心的服務,調(diào)度中心維護訂單的信息,但它不與子服務通訊,而是通過消息隊列和出票網(wǎng)關(guān),算獎服務等系統(tǒng)傳遞和交換信息。

          消息總線這種架構(gòu)設計,可以讓系統(tǒng)更加解耦,同時也可以讓每個系統(tǒng)各司其職。

          4 延時任務

          用戶在美團 APP 下單,假如沒有立即支付,進入訂單詳情會顯示倒計時,如果超過支付時間,訂單就會被自動取消。

          非常優(yōu)雅的方式是:使用消息隊列的延時消息

          訂單服務生成訂單后,發(fā)送一條延時消息到消息隊列。消息隊列在消息到達支付過期時間時,將消息投遞給消費者,消費者收到消息之后,判斷訂單狀態(tài)是否為已支付,假如未支付,則執(zhí)行取消訂單的邏輯。

          RocketMQ 4.X 生產(chǎn)者發(fā)送延遲消息代碼如下:

          Message msg = new Message();
          msg.setTopic("TopicA");
          msg.setTags("Tag");
          msg.setBody("this is a delay message".getBytes());
          //設置延遲level為5,對應延遲1分鐘
          msg.setDelayTimeLevel(5);
          producer.send(msg);

          RocketMQ 4.X 版本默認支持 18 個 level 的延遲消息, 通過 broker 端的 messageDelayLevel 配置項確定的。

          RocketMQ 5.X 版本支持任意時刻延遲消息,客戶端在構(gòu)造消息時提供了 3 個 API 來指定延遲時間或定時時間。

          5 廣播消費

          廣播消費是指每條消息推送給集群內(nèi)所有的消費者,保證消息至少被每個消費者消費一次。

          廣播消費主要用于兩種場景:消息推送緩存同步

          01 消息推送

          下圖是專車的司機端推送機制,用戶下單之后,訂單系統(tǒng)生成專車訂單,派單系統(tǒng)會根據(jù)相關(guān)算法將訂單派給某司機,司機端就會收到派單推送消息。

          推送服務是一個 TCP 服務(自定義協(xié)議),同時也是一個消費者服務,消息模式是廣播消費。

          司機打開司機端 APP 后,APP 會通過負載均衡和推送服務創(chuàng)建長連接,推送服務會保存 TCP 連接引用 (比如司機編號和 TCP channel 的引用)。

          派單服務是生產(chǎn)者,將派單數(shù)據(jù)發(fā)送到 MetaQ ,  每個推送服務都會消費到該消息,推送服務判斷本地內(nèi)存中是否存在該司機的 TCP channel , 若存在,則通過 TCP 連接將數(shù)據(jù)推送給司機端。

          02 緩存同步

          高并發(fā)場景下,很多應用使用本地緩存,提升系統(tǒng)性能 。

          本地緩存可以是 HashMap 、ConcurrentHashMap ,也可以是緩存框架 Guava Cache 或者 Caffeine cache 。

          如上圖,應用A啟動后,作為一個 RocketMQ 消費者,消息模式設置為廣播消費。為了提升接口性能,每個應用節(jié)點都會將字典表加載到本地緩存里。

          當字典表數(shù)據(jù)變更時,可以通過業(yè)務系統(tǒng)發(fā)送一條消息到 RocketMQ ,每個應用節(jié)點都會消費消息,刷新本地緩存。

          6 分布式事務

          以電商交易場景為例,用戶支付訂單這一核心操作的同時會涉及到下游物流發(fā)貨、積分變更、購物車狀態(tài)清空等多個子系統(tǒng)的變更。

          1、傳統(tǒng)XA事務方案:性能不足

          為了保證上述四個分支的執(zhí)行結(jié)果一致性,典型方案是基于 XA 協(xié)議的分布式事務系統(tǒng)來實現(xiàn)。將四個調(diào)用分支封裝成包含四個獨立事務分支的大事務。基于 XA 分布式事務的方案可以滿足業(yè)務處理結(jié)果的正確性,但最大的缺點是多分支環(huán)境下資源鎖定范圍大,并發(fā)度低,隨著下游分支的增加,系統(tǒng)性能會越來越差。

          2、基于普通消息方案:一致性保障困難

          該方案中消息下游分支和訂單系統(tǒng)變更的主分支很容易出現(xiàn)不一致的現(xiàn)象,例如:

          • 消息發(fā)送成功,訂單沒有執(zhí)行成功,需要回滾整個事務。
          • 訂單執(zhí)行成功,消息沒有發(fā)送成功,需要額外補償才能發(fā)現(xiàn)不一致。
          • 消息發(fā)送超時未知,此時無法判斷需要回滾訂單還是提交訂單變更。

          3、基于 RocketMQ 分布式事務消息:支持最終一致性

          上述普通消息方案中,普通消息和訂單事務無法保證一致的原因,本質(zhì)上是由于普通消息無法像單機數(shù)據(jù)庫事務一樣,具備提交、回滾和統(tǒng)一協(xié)調(diào)的能力。

          而基于 RocketMQ 實現(xiàn)的分布式事務消息功能,在普通消息基礎(chǔ)上,支持二階段的提交能力。將二階段提交和本地事務綁定,實現(xiàn)全局提交結(jié)果的一致性

          交互流程如下圖所示:

          1、生產(chǎn)者將消息發(fā)送至 Broker 。

          2、Broker 將消息持久化成功之后,向生產(chǎn)者返回 Ack 確認消息已經(jīng)發(fā)送成功,此時消息被標記為"暫不能投遞",這種狀態(tài)下的消息即為半事務消息

          3、生產(chǎn)者開始執(zhí)行本地事務邏輯

          4、生產(chǎn)者根據(jù)本地事務執(zhí)行結(jié)果向服務端提交二次確認結(jié)果( Commit 或是 Rollback ),Broker 收到確認結(jié)果后處理邏輯如下:

          • 二次確認結(jié)果為 Commit :Broker 將半事務消息標記為可投遞,并投遞給消費者。
          • 二次確認結(jié)果為 Rollback :Broker 將回滾事務,不會將半事務消息投遞給消費者。

          5、在斷網(wǎng)或者是生產(chǎn)者應用重啟的特殊情況下,若 Broker 未收到發(fā)送者提交的二次確認結(jié)果,或 Broker 收到的二次確認結(jié)果為 Unknown 未知狀態(tài),經(jīng)過固定時間后,服務端將對消息生產(chǎn)者即生產(chǎn)者集群中任一生產(chǎn)者實例發(fā)起消息回查

          1. 生產(chǎn)者收到消息回查后,需要檢查對應消息的本地事務執(zhí)行的最終結(jié)果。
          2. 生產(chǎn)者根據(jù)檢查到的本地事務的最終狀態(tài)再次提交二次確認,服務端仍按照步驟4對半事務消息進行處理。

          7 數(shù)據(jù)中轉(zhuǎn)樞紐

          近10多年來,諸如 KV 存儲(HBase)、搜索(ElasticSearch)、流式處理(Storm、Spark、Samza)、時序數(shù)據(jù)庫(OpenTSDB)等專用系統(tǒng)應運而生。這些系統(tǒng)是為單一的目標而產(chǎn)生的,因其簡單性使得在商業(yè)硬件上構(gòu)建分布式系統(tǒng)變得更加容易且性價比更高。

          通常,同一份數(shù)據(jù)集需要被注入到多個專用系統(tǒng)內(nèi)。

          例如,當應用日志用于離線日志分析時,搜索單個日志記錄同樣不可或缺,而構(gòu)建各自獨立的工作流來采集每種類型的數(shù)據(jù)再導入到各自的專用系統(tǒng)顯然不切實際,利用消息隊列 Kafka 作為數(shù)據(jù)中轉(zhuǎn)樞紐,同份數(shù)據(jù)可以被導入到不同專用系統(tǒng)中。

          日志同步主要有三個關(guān)鍵部分:日志采集客戶端,Kafka 消息隊列以及后端的日志處理應用。

          1. 日志采集客戶端,負責用戶各類應用服務的日志數(shù)據(jù)采集,以消息方式將日志“批量”“異步”發(fā)送Kafka客戶端。Kafka客戶端批量提交和壓縮消息,對應用服務的性能影響非常小。
          2. Kafka 將日志存儲在消息文件中,提供持久化。
          3. 日志處理應用,如 Logstash,訂閱并消費Kafka中的日志消息,最終供文件搜索服務檢索日志,或者由 Kafka 將消息傳遞給 Hadoop 等其他大數(shù)據(jù)應用系統(tǒng)化存儲與分析。
          END


          Java項目訓練營

          我開通了項目股東服務,已經(jīng)有不少消息推送平臺項目股東拿了阿里/vivo等大廠offer了。我是沒找到網(wǎng)上有跟我提供相同的服務,價格還比我低的

          ??一對一周到的服務:有很多人的自學能力和基礎(chǔ)確實不太行,不知道怎么開始學習,從哪開始看起,學習項目的過程中會走很多彎路,很容易就迷茫了。付費最跟自學最主要的區(qū)別就是我的服務會更周到。我會告訴你怎么開始學這個開源項目,哪些是重點需要掌握的,如何利用最短的時間把握整個系統(tǒng)架構(gòu)和編碼的設計,把時間節(jié)省下來去做其他事情。學習經(jīng)驗/路線/簡歷編寫/面試經(jīng)驗知無不言

          ??本地直連遠程服務:生產(chǎn)環(huán)境的應用系統(tǒng)肯定會依賴各種中間件,我專門買了兩臺服務器已經(jīng)搭建好必要的環(huán)境??,在本地就可以直接啟動運行體驗和學習,無須花額外的時間自行搭建調(diào)試。

          ??細致的文檔&視頻:巨細致的語雀文檔11W+ 字,共106個文檔,項目視頻還在持續(xù)制作更新中(20個),不怕你學不會。

          ??付費社群優(yōu)質(zhì)的社群里需篩選過濾,學習氛圍是很重要的,多跟同輩或前輩聊聊,會少走很多彎路??

          ??清爽干練commit:專屬股東倉庫,一步一步從零復現(xiàn)austin,每個commit都帶著文檔&視頻學習。

          如果想獲取上面的權(quán)益,可以看看??Java項目訓練營

          瀏覽 52
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产乱伦高清无码 | 91欧美亚洲 | 欧美黄色影院 | 中文天堂视频在线 | 黑人巨大开小嫩苞 |