<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>

          你必須知道的消息的推拉機制

          共 3666字,需瀏覽 8分鐘

           ·

          2021-11-01 18:36


          大家好,我是Captain


          e23ec373718c70dc5eec86d72759caac.webp


          我們在之前也說了不少RocketMQ的知識點了,這一篇要說的是RocketMQ的消息的推拉機制,這個應(yīng)該也是屬于面試的熱點,學(xué)起來吧


          先撈一撈之前的文章



          我們下面要說的推拉模式指的是broker和consumer之間的,producer和broker之間的模式是推的模式,也就是每次producer每次生產(chǎn)了消息,會主動推給broker


          其實這個大家也應(yīng)該好理解,如果producer和broker之間交互用broker來拉取,就會怪怪的,每次消息都要存儲到producer的本地,然后等待broker來拉取,這個要取決于多個producer的可靠性,顯然這種設(shè)計是很糟糕的


          我們下面要討論的是broker和consumer之間的交互是推還是拉,大家也可以自己先思考下到底是推還是拉


          a13b36333e37815ba7747b71fc8c814f.webp


          說一下推模式以及優(yōu)缺點


          推模式指的是broker將消息推向Consumer,也就是Consumer是被動的去接收這個消息,broker來將消息主動的去推給Consumer


          那么這種模式的優(yōu)缺點呢,大家可以想一下


          很明顯的一個優(yōu)點就是延遲小,實時性比較好,broker接收到消息之后就會立刻推送到Consumer,實時性相對來說是比較高的


          還有一個優(yōu)點其實就是簡化了Consumer端的邏輯,消費端不需要自己去處理這個拉取的邏輯,只需要監(jiān)聽這個消息的topic,然后去專心的處理這個消息的業(yè)務(wù)邏輯即可


          ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?d1ca27105e19e1d69c2561da0e2d886c.webp


          上面說的兩點是優(yōu)點,那么有優(yōu)點就肯定也會伴隨相應(yīng)的缺點


          第二點簡化了Consumer消費端的邏輯的同時,也就復(fù)雜化了broker端的邏輯,這其實也不算是優(yōu)點或者缺點吧,算是這個模式的一個特點,需要根據(jù)場景來選擇自己合適的模式


          最大的一個缺點就是推送的速率和消費的速率不好去匹配,這樣就是很糟糕的,你想,如果broker拿到消息就推給Consumer,不在乎Consumer的消費能力如何,就往Consumer直接扔,那Consumer有可能會崩潰


          就像一個生產(chǎn)線,本來只能接收的最大速度是10立方米每秒,結(jié)果呢,你每秒往生產(chǎn)線上扔100立方米每秒,那這個生產(chǎn)線可能就因為無法處理而直接崩盤


          當推送速率很快的時候,甚至都像DDos的攻擊一樣,消費者就更難受了,不同的消費者的消費速率也是不一樣的,broker也很難平衡每個消費者的速率,如果broker需要記住每個Consumer的消費能力和速度的話,那broker的復(fù)雜度可就直線上升


          還以一個缺點就是消費者推出去之后,無法保證消息發(fā)送成功,push采用的是廣播模式,也就是只有服務(wù)端和客戶端都在同一個頻道的時候,推模式才可以成功的將消息推到消費者


          分析一下拉模式以及優(yōu)缺點


          拉模式,也是同樣的道理,就是Consumer是主動從broker拉取消息,哎,這次我Consumer主動了,我不需要你來喂我了,我每過一段時間去你那里拿消息就好了,你也別在乎我的消費速率了


          e6bd5ff01a452050c10f63d97232b9e7.webp


          咋回事知道了,想想這樣的優(yōu)缺點,知道了優(yōu)缺點就對這個模式肯定了解的八九不離十了


          最大的優(yōu)點就是主動權(quán)掌握在Consumer這邊了,每個消費者的消費能力可能不一樣,消費者可以根據(jù)自身的情況來拉取消息的請求,如果消費者真的出現(xiàn)那種忙不過來的情況下,可以根據(jù)一定的策略去暫停拉取


          服務(wù)端也相對來說輕松了,不需要去進行消息的處理邏輯了,你來了我就給你就好了,你要多少我就給你就好了,broker就是一個沒得感情的存儲機器


          拉模式也更適合批量消息的發(fā)送,推模式是來一個消息就推一個,當然也可以緩存一部分消息再推送,但是無法確定Consumer是否能夠處理這批推送的消息,拉模式則是Consumer主動來告訴broker,這樣broker也可以更好的決定緩存多少消息用于批量發(fā)送


          說完了優(yōu)點,就需要說缺點了,拉模式需要Consumer對于服務(wù)端有一定的了解,主要的缺點就是實時性較差,針對于服務(wù)器端的實時更新的信息,客戶端還是難以獲取實時的信息


          畢竟消費者是去拉取消息,消費者怎么知道消息到了呢,所以消費者能做的就是不斷的去拉取,但是又不能頻繁的去拉取,這樣也耗費性能,因此就必須降低請求的頻率,請求間隔時間也就意味著消息的延遲


          RocketMQ最終的選擇呢,為什么是拉模式


          RocketMQ最終決定的拉模式,kafka也是如此


          RocketMQ的使用的拉模式的使用特點


          • 自己維護offsetStore:用戶需要自己保存消費者組的offset,比如存入Redis,或者調(diào)用MQ接口將其保存到broker端


          • 自主選擇MessageQueue和offset進行消息拉取,用戶拉取消息的時候,用戶自己決定拉取哪個隊列從哪個offset開始,拉取多少消息


          為什么拉模式稍微更合適些呢,現(xiàn)在的消息隊列都有持久化消息的需求,削峰主要就是靠持久化來削的,也就是本身需要有個存儲的功能,它的使命就是接受消息,保存好消息,然后等著消費者來拉取就好了


          消費者也是各種各樣,消費者的能力也是參差不齊,所以broker不能和Consumer有太多依賴


          拉模式也是有缺點的,上面我們也說過了,最大的缺點就是實時性比較差,所以RocketMQ也盡力的去操作減輕這些缺點


          broker來消息的時候,broker會去提醒Consumer來消息了,需要來拉取消息了,總之,就是broke和Consumer相互打配合,下面會詳細說


          RocketMQ是如何實現(xiàn)拉模式的


          拉模式指的是Consumer主動去找broker拉取消息,拉取模式分為普通輪詢和長輪詢兩種方式


          ? ? 1、普通輪詢也是比較簡單的,就是定時發(fā)起請求,服務(wù)端收到請求之后無論是否有數(shù)據(jù)更新,都立即回復(fù),也是屬于比較好理解的,實現(xiàn)起來也是比較簡單的,缺點呢,就是broker比較被動,需要不斷的處理客戶端連接的,就是服務(wù)端屬于一種有求必應(yīng)的方式


          ? ?2、長輪詢就是屬于對普通輪詢的一種優(yōu)化,當然也是Consumer向服務(wù)端發(fā)起請求,而服務(wù)端收到后不會立即去響應(yīng),而是hold住客戶端連接,等待數(shù)據(jù)產(chǎn)生變更之后才會回復(fù)客戶端,或者超過指定時間還未產(chǎn)生變更


          其實說白了,就是對普通輪詢進行一定程度的限制,客戶端可以隨時請求服務(wù)端,但是我并不一定立即回復(fù)你


          ? ? ? ? ? ? ? ? ? ? ? ?f85e79411dfff40789a73c7ade81c79c.webp


          RocketMQ就是使用長輪詢來實現(xiàn)拉模式,Consumer發(fā)起pull請求之后,broker在處理請求拉取消息的時候,如果沒有查詢到消息則不會回復(fù)消費者任何消息,而是等待觸發(fā)通知消費者的這個事件


          這里會有兩種觸發(fā)事件的條件:


          1、DefaultMessageStore.ReputMessageService.run,一個定時任務(wù),1毫秒一次,不斷的檢查是否有消息的產(chǎn)生,如果檢測到了,就會通知消費者,將新消息發(fā)送給消費者


          2、PullRequestHoldService.run也是定時任務(wù),5秒一次,該任務(wù)會逐個的檢查其中的請求,判斷是否有對應(yīng)的新消息產(chǎn)生,如果有直接返回消費者,沒有就檢查該請求是否超過默認的長輪詢等待時間(默認15秒),如果超出,則返回消費者


          那pushConsumer怎么說?


          RocketMQ中的PushConsumer其實底層也是拉模式實現(xiàn)的,只是一層披著拉模式的狼而已


          因為RocketMQ后臺有個ReblanceService線程會自己偷偷的去找broker請求數(shù)據(jù),這個線程會根據(jù)topic的隊列數(shù)量和當前的消費組的消費者個數(shù)進行負載均衡,每個隊列產(chǎn)生的請求都會放入到阻塞隊列中


          然后有一個PullMessageService線程不斷的從該阻塞隊列中獲取請求,然后通過網(wǎng)絡(luò)請求broker,這樣算是實現(xiàn)了一種準實時的拉取消息


          源碼在PullMessageProcessor里面的processRequest方法,用來處理拉消息的請求,有消息返回,沒有消息就進入了上述說的長輪詢過程,這部分源碼我就不截了,大家感興趣的可以去研究研究



          佛系求關(guān)注



          Captain希望有一天能夠靠寫作養(yǎng)活自己,現(xiàn)在還在磨練,這個時間可能會持續(xù)很久,但是,請看我漂亮的堅持


          感謝大家能夠做我最初的讀者和傳播者,請大家相信,只要你給我一份愛,我終究會還你們一頁情的。


          Captain會持續(xù)更新技術(shù)文章,和生活中的暴躁文章,歡迎大家關(guān)注【Java賊船】,成為船長的學(xué)習(xí)小伙伴,和船長一起乘千里風(fēng)、破萬里浪


          哦對了,后續(xù)所有的遠程文章都會更新到這里


          https://github.com/DayuMM2021/Java


          45108af978205992c597cc2f38c7501c.webp


          瀏覽 142
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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香蕉视频1区 |