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

          RabbitMQ如何保證消息的可靠性

          共 2488字,需瀏覽 5分鐘

           ·

          2021-08-01 16:24

          點擊上方藍色字體,選擇“標星公眾號”

          優(yōu)質(zhì)文章,第一時間送達

          1、保證消息不丟失(三步)
          1.1、開啟事務(wù)(不推薦)
          1.2、開啟confirm(推薦)
          1.3、開啟RabbitMQ持久化(交換機、隊列、消息)
          1.4、關(guān)閉RabbitMQ自動ack(改成手動)

          2、保證消息不重復(fù)消費
          2.1、冪等性(每個消息用一個唯一標識來區(qū)分,消費前先判斷標識有沒有被消費過,若已消費過,則直接ACK)

          3、RabbitMQ如何保證消息的順序性
          將消息放入同一個交換機,交給同一個隊列,這個隊列只有一個消費者,消費者只允許同時開啟一個線程

          4、RabbitMQ消息重試機制
          消費者在消費消息的時候,如果消費者業(yè)務(wù)邏輯出現(xiàn)程序異常,這時候應(yīng)該如何處理?
          答案:使用消息重試機制(SpringBoot默認3次消息重試機制)

          如何合適選擇重試機制
          消費者取到消息后,調(diào)用第三方接口,接口無法訪問,需要使用重試機制
          消費者取到消息后,拋出數(shù)據(jù)轉(zhuǎn)換異常,不需要重試機制,需要發(fā)布者進行解決。

          5、SpringBoot消息重試機制
          @EnableRetry注解:表示啟用重試機制(value表示哪些異常需要觸發(fā)重試,maxAttempts設(shè)置最大重試次數(shù),delay表示重試的延遲時間,multiplier表示上一次延時時間是這一次的倍數(shù))
          eg、@Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000, multiplier = 1.5))

          @Recover注解:當重試次數(shù)達到設(shè)置的最大次數(shù)的時候,程序還是執(zhí)行異常,調(diào)用的回調(diào)函數(shù)。

          6、RabbitMQ死信隊列
          死信隊列是當消息在一個隊列因為下列原因:
          a、消息被拒絕(basic.reject或basic.nack)并且requeue=false.
          b、消息TTL過期
          c、隊列達到最大長度(隊列滿了,數(shù)據(jù)無法添加到mq中)
          變成了 “死信隊列” 后被重新投遞(publish)到另一個Exchange,然后重新消費。說白了就是沒有被消費的消息換個地方重新被消費

          7、RabbitMQ解決分布式事務(wù)

          經(jīng)典案例,以目前流行的外賣為例,用戶下單后,調(diào)用訂單服務(wù),訂單服務(wù)調(diào)用派單系統(tǒng)通知送外賣人員送單,這時候訂單系統(tǒng)與派單系統(tǒng)采用MQ異步通訊。

          RabbitMQ解決分布式事務(wù)原理
          答案:采用最終一致性原理

          需要保證以下三要素:
          a、確保生產(chǎn)者一定要將數(shù)據(jù)投遞到MQ服務(wù)器中(采用MQ消息確認機制)
          b、確保消費者能夠正確消費消息,采用手動ACK模式(注意重試、冪等性問題)
          c、如何保證第一個事務(wù)先執(zhí)行,采用補償機制,在創(chuàng)建一個補單消費者進行監(jiān)聽,如果訂單沒有創(chuàng)建成功,進行補單。(如果第一個事務(wù)中出錯,補單消費者會在重新執(zhí)行一次第一個事務(wù),例如第一個事務(wù)是添加訂單表,如果失敗在補單的時候重新生成訂單記錄,由于訂單號唯一,所以不會重復(fù))

          8、RabbitMQ保證消息不丟失的具體方案
          前提:
          (1)開啟confirm
          (2)開啟RabbitMQ的持久化(交換機、隊列、消息)
          (3)關(guān)閉RabbitMQ的自動ack(改成手動)
          (4)配置消費重試次數(shù),消費重試間隔時間等

          涉及到的技術(shù)點:
          MQ、Redis、定時任務(wù)

          8.1、保證投放消息不丟失
          (1)先將消息放入生產(chǎn)者Redis(此時消息的狀態(tài)為未投放),再放入隊列
          (2)根據(jù)confirm(ReturnCallback和ConfirmCallback)的結(jié)果來確定消息是否投遞成功,
          投遞成功的,修改生產(chǎn)者redis中消息的投遞狀態(tài)為已投遞
          投遞失敗的消息將會放入失敗的Redis,并從生產(chǎn)者Redis中刪除,由定時任務(wù)定期掃描并重新投遞

          (3)生產(chǎn)者Redis定時任務(wù)
          生產(chǎn)者Redis定時任務(wù)專門掃描生產(chǎn)者Redis中存放了一定時間,但是狀態(tài)還是未投放的消息
          此消息會被認為已經(jīng)投遞,但是沒有任何反饋結(jié)果(由于不可知因素,導致沒有ReturnCallback,也沒有ConfirmCallback),
          此類消息被掃描到后,會放入失敗的Redis,并從生產(chǎn)者Redis中刪除,由定時任務(wù)定期掃描并重新投遞
          (4)還需要一個專門的定時任務(wù)掃描生產(chǎn)者Redis中存放了很久,仍然未消費的數(shù)據(jù)(狀態(tài)為已投遞),此類消息被掃描到后,會放入失敗的Redis,并從生產(chǎn)者Redis中刪除,由定時任務(wù)定期掃描并重新投遞
          (5)掃描失敗的Redis的定時任務(wù)都遵循一條原則,一條消息最多被重新投遞三次,若投遞了三次仍然失敗,則記錄日志,記錄到數(shù)據(jù)庫,不會再投遞,需要人工干預(yù)處理

          8.2、保證消費消息不丟失
          (1)消費者取到消息后,從消息中取出唯一標識,先判斷此消息有沒有被消費過,若已消費過,則直接ACK(避免重復(fù)消費)
          (2)正常處理成功后,將生產(chǎn)者Redis中的此消息刪除,并ACK(告訴server端此消息已成功消費)
          (3)遇到異常時,捕獲異常,驗證自己在消息中設(shè)定的重試次數(shù)是否超過閥值,若超過,則放入死信隊列,若未超過,則向?qū)⑾⒅械闹卦嚧螖?shù)加1,拋出自定義異常,進入重試機制
          (4)有專門的消費者用于處理死信隊列中消費多次仍未消費成功的數(shù)據(jù),可以記錄日志,入庫,人工干預(yù)處理


            作者 |  Ruthless

          來源 |  cnblogs.com/linjiqin/p/12683076.html


          加鋒哥微信: java3459  
          圍觀鋒哥朋友圈,每天推送Java干貨!

          瀏覽 60
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  影音先锋男人站你懂的 | 处一女一级a一片 | 亚洲人的天堂 | 五月婷婷狠 | 天堂AV2014 |