天天看點

RabbitMQ消息隊列之實作可靠投遞的請求-确認機制(下)2 returnCallback 未投遞到queue退回模式1 Producer 的可靠性投遞總結

2 returnCallback 未投遞到queue退回模式

confrim 模式僅保證消息到達 broker,無法保證消息準确投遞到目标 queue。

有些業務場景下,我們需保證消息一定要投遞到目标 queue,這時就要用到 return 退回模式。

同樣建立 ConnectionFactory 到時候需要設定 PublisherReturns(true) 選項。

CachingConnectionFactory factory = new CachingConnectionFactory();
factory.setPublisherReturns(true);//開啟return模式      
rabbitTemplate.setMandatory(true);//開啟強制委托模式

rabbitTemplate.setReturnCallback((message, replyCode, replyText,
                    exchange, routingKey) ->
    log.info(MessageFormat.format("消息發送ReturnCallback:{0},{1},{2},{3},{4},{5}", message, replyCode, replyText, exchange, routingKey)));      

這樣如果未能投遞到目标 queue 裡将調用 returnCallback ,可以記錄下詳細到投遞資料,定期的巡檢或者自動糾錯都需要這些資料。

1 Producer 的可靠性投遞

1.1 要求

  1. 保證消息的成功發出
  2. 保證MQ節點的成功接收
  3. 發送端收到MQ節點(Broker) 确認應答
  4. 完善的消息補償機制

在實際生産中,很難保障前三點完全可靠。在極端環境,生産者發送消息失敗,發送端在接受确認應答時突然發生網絡閃斷等,很難保障可靠性投遞,是以就需第四點完善的消息補償機制。

1.2 解決方案

1.2.1 消息信心落庫,對消息狀态進行打标(常見方案)

将消息持久化到DB并設定狀态值,收到Consumer的應答就改變目前記錄的狀态.

再輪詢重新發送沒接收到應答的消息,注意這裡要設定重試次數.

方案流程圖
RabbitMQ消息隊列之實作可靠投遞的請求-确認機制(下)2 returnCallback 未投遞到queue退回模式1 Producer 的可靠性投遞總結
方案實作流程

比如我下單成功

step1 - 對訂單資料入BIZ DB訂單庫,并對是以生成的業務消息入MSG DB消息庫

此處由于采用了兩個資料庫,需要兩次持久化操作,為了保證資料的一緻性,有人可能就想着采用分布式事務,但在大廠實踐中,基本都是采用補償機制!

這裡一定要保證step1 中消息都存儲成功了,沒有出現任何異常情況,然後生産端再進行消息發送。如果失敗了就進行快速失敗機制

RabbitMQ消息隊列之實作可靠投遞的請求-确認機制(下)2 returnCallback 未投遞到queue退回模式1 Producer 的可靠性投遞總結

1.2.2 消息延遲投遞,兩次确認,回調檢查(大規模海量資料方案)

大廠經典實作方案。當然這種方案不一定能保障百分百投遞成功,但是基本上可以保障大概99.9%的消息是OK的,有些特别極端的情況隻能是人工去做補償了,或者使用定時任務。主要就是為了減少DB操作。

流程圖

RabbitMQ消息隊列之實作可靠投遞的請求-确認機制(下)2 returnCallback 未投遞到queue退回模式1 Producer 的可靠性投遞總結
  • Upstream Service

    上遊服務,即生産端

  • Downstream service

    下遊服務,即消費端

  • Callback service

    回調服務

  • MQ Broker

    消息隊列的叢集

RabbitMQ消息隊列之實作可靠投遞的請求-确認機制(下)2 returnCallback 未投遞到queue退回模式1 Producer 的可靠性投遞總結

設計目的

少做一次DB的存儲。

在高并發場景下,最關心的不是消息百分百投遞成功,而是保證性能,保證能抗得住這麼大的并發量。是以能節省DB操作就盡量節省,異步進行補償。

其實在主流程裡面是沒有Callback service的,它屬于一個補償的服務,整個核心鍊路就是Pro入庫業務消息,發送消息到MQ,Con監聽隊列,消費消息。其他的步驟都是一個補償機制。

總結

這兩種方案都可行。

需要根據實際業務來進行選擇,方案二也是網際網路大廠更為經典和主流的解決方案。但是若對性能要求不是那麼高,方案一要更簡單。

參考

https://www.cnblogs.com/wangiqngpei557/p/9381478.html