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 要求
- 保證消息的成功發出
- 保證MQ節點的成功接收
- 發送端收到MQ節點(Broker) 确認應答
- 完善的消息補償機制
在實際生産中,很難保障前三點完全可靠。在極端環境,生産者發送消息失敗,發送端在接受确認應答時突然發生網絡閃斷等,很難保障可靠性投遞,是以就需第四點完善的消息補償機制。
1.2 解決方案
1.2.1 消息信心落庫,對消息狀态進行打标(常見方案)
将消息持久化到DB并設定狀态值,收到Consumer的應答就改變目前記錄的狀态.
再輪詢重新發送沒接收到應答的消息,注意這裡要設定重試次數.
方案流程圖
方案實作流程
比如我下單成功
step1 - 對訂單資料入BIZ DB訂單庫,并對是以生成的業務消息入MSG DB消息庫
此處由于采用了兩個資料庫,需要兩次持久化操作,為了保證資料的一緻性,有人可能就想着采用分布式事務,但在大廠實踐中,基本都是采用補償機制!
這裡一定要保證step1 中消息都存儲成功了,沒有出現任何異常情況,然後生産端再進行消息發送。如果失敗了就進行快速失敗機制
1.2.2 消息延遲投遞,兩次确認,回調檢查(大規模海量資料方案)
大廠經典實作方案。當然這種方案不一定能保障百分百投遞成功,但是基本上可以保障大概99.9%的消息是OK的,有些特别極端的情況隻能是人工去做補償了,或者使用定時任務。主要就是為了減少DB操作。
流程圖
-
Upstream Service
上遊服務,即生産端
-
Downstream service
下遊服務,即消費端
-
Callback service
回調服務
-
MQ Broker
消息隊列的叢集
設計目的
少做一次DB的存儲。
在高并發場景下,最關心的不是消息百分百投遞成功,而是保證性能,保證能抗得住這麼大的并發量。是以能節省DB操作就盡量節省,異步進行補償。
其實在主流程裡面是沒有Callback service的,它屬于一個補償的服務,整個核心鍊路就是Pro入庫業務消息,發送消息到MQ,Con監聽隊列,消費消息。其他的步驟都是一個補償機制。
總結
這兩種方案都可行。
需要根據實際業務來進行選擇,方案二也是網際網路大廠更為經典和主流的解決方案。但是若對性能要求不是那麼高,方案一要更簡單。
參考
https://www.cnblogs.com/wangiqngpei557/p/9381478.html