史上最簡單的RabbitMQ教程 | 第三篇: RabbitMQ高級特性之保證消息可靠性投遞和消費


    保證消息的可靠性投遞和消費,將分為兩部分來進行,第一部分來描述消息的可靠性投遞,包含目前流行的兩種可靠性投遞架構,第二部分將描述消息的可靠性消費,包含消息冪等性介紹等。第三部分將結合RabbitMQ來講述下怎么保證消息不丟失。通過本篇的學習,可以學習到消息可靠性的投遞、消費以及怎樣保證消息不丟失。

消息可靠性投遞

執行步驟:

    1. 保障消息成功發出

    2. 保證MQ節點成功接收

    3. 發送端收到消費端的確認應答

    4. 完善的消息補償機制

解決方案:

    1. 業務和消息同時入庫,對消息進行處理修改標記

    2. 消息延遲投遞,做二次確認,回調檢查

可靠性投遞方案一:消息入庫,對消息打標

1. 流程圖如下

2. 流程拆解

    ①:消息和業務記錄入庫

    ②:第一步正常執行完后,將消息發送個MQ

    ③:消息處理完,發送確認消息給MQ

    ④:更新消息的狀態

    ⑤:定時任務讀取消息的狀態

    ⑥:如果消息處理工程,流程結束,否則讀消息重發MQ

    ⑦:重試次數內,重復執行流程;超過重試次數,將數據庫更新狀態

    ⑧:補償系統,解決超過重試次數消息,保障消息的100%投遞

3. 方案問題

    兩次數據入庫,不適合在高並發場景使用。

可靠性投遞方案二:消息延遲發送,做二次檢查,回調檢查

1. 流程圖如下

2. 流程拆解

    ①:業務記錄入庫,業務記錄正常入庫后向MQ發送消息

    ②:第二次消息延遲3-5分鍾,向MQ發送消息

    ③:消費監聽隊列,消費消息

    ④:消費者消費完后,發送確認消息給MQ的一個隊列

    ⑤:另外一個服務監聽消費者發送的confirm消息,如果正常完成,消息入庫。

    ⑥:另外服務,經停延遲發送的隊列,那消息檢查msg數據庫,如果沒有,將再msg上新插入一條消息,用來記錄重試次數

    ⑦:延遲檢查成功,不需要任何操作;如果檢查不成功,將通知服務,重新發消息給MQ

    ⑧:補償系統,解決超過重試次數消息,保障消息的100%投遞

消息可靠性消費-不重復消費

    消息保證不重復消費,就要保證消息的冪等性,什么是冪等性?

    冪等性:指消息執行一次和執行多次的結果相同,就說明消息是冪等的。

保證消息冪等性:

    1. 通過數據庫主鍵形式(ID+指紋碼)

    2. 使用Redis原子性保證冪等性

保證冪等性方案一:通過數據庫主鍵形式(ID+指紋碼)

    指紋碼:是唯一的系統碼,可以是內部規則(如時間戳)和外部返回(如銀行流水號),通過指紋碼和全局唯一ID做主鍵,利用數據庫主鍵進行去重。

    使用指紋碼避免用戶在一個唯一主鍵可能因為網絡延遲等問題,對數據庫進行多次寫操作。

1. 實現

    select * from table where id=唯一id+指紋碼

    實現簡單,但在高並發情況下存在數據庫寫入性能的瓶頸。多余指紋碼加大主鍵長度影響存儲。

2. 解決方案

    數據庫采用分庫分表,將id根據規則分布到不同的數據庫表中,單一數據庫分流降壓。

保證冪等性方案二:利用Redis原子性操作保證冪等性

1. 實現

   這種性能高,Redis是基於內存,不會造成數據庫瓶頸。

2. 問題

    ①Redis數據庫是否需要入庫,怎樣保證數據庫和Redis中數據一致性(一般保證冪等是不需入庫)

    ②如果不入庫,怎樣保證定時清理策略,緩存得可靠性保證(高可用-集群,定期清理策略)

RabbitMQ保障消息的可靠性傳輸

    可靠性傳輸就是保證不丟失數據,丟失數據一般分為兩部分,分別是MQ丟失數據,另外是我們生產消費消息時丟失數據。具體細分的包含生產者保證消息不丟失,MQ保證消息不丟失和消費者保證消息不丟失。

消息可靠性傳遞一:生產者保證消息不丟失

     生產者保證數據不丟失可以采取兩種方式:

    1. 使用RabbitMQ事務,在發送消息之前開啟事務(channel.txSelect),正常發送后提交事務(channel.txCommit),如果出現異常,需要回滾事務(channel.txRollback)做消息重發等操作

        缺點:RabbitMQ事務采用同步的方式進行事務處理,提交一個事務后,事務阻塞在哪,只有等這個事務執行完才能執行下一個事務,嚴重影響RabbitMQ性能,在 實際生產中不使用。

    2. 使用confirm模式,生產者開始confirm模式后,每次寫數據會分配唯一id,當消息成功處理,將回傳ack,消息處理失敗,回傳nack。

        優點:采用異步模式,消費者發送一條消息后,不用等消息回傳消息,就可以發送下一條消息,RabbitMQ將異步接受這條回傳信息,如果是nack,將進行消息重試。實際生產中使用這種方式。

        類型:普通Confirm模式 批量Confirm模式 異步Confirm模式,將再以后的博客中詳細介紹3中不同的confirm類型    

消息可靠性傳遞二:RabbitMQ保證消息不丟失

     保證RabbitMQ消息不丟失,需要兩步操作;

        1. 創建queue時,將queue設置為持久化,

        2. 發送消息的時,設置消息的deliveryMode=2。

    即使這樣操作,還可能存在,消息寫到RabbitMQ中,但是消息沒有持久化磁盤,這是服務器重啟,這部分數據丟失。

消息可靠性傳遞三:消費者保證消息不丟失

     消費端關閉自動應答,設置手動應答。

    autoAck=false; 這樣保證消費者消費消息后,刪除RabbitMQ中數據。

小結

    1. 兩種可靠性投遞,第一種執行簡單,但是不適合高並發環境;第二種執行復雜,但是減少一次數據入庫,性能會有提高,適合高並發環境。如果MQ所在的服務器宕機,MQ中沒有及時消費的數據會丟失

    2. 保證冪等性可以采用兩種方式,第一種是主鍵方式,第二種采用Redis原子性,根據業務場景的不同來選擇。

    3. 詳細講解RabbitMQ的消息可靠性傳遞,並從生產者,消費者和RabbitMQ來保證消息不丟失。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM