複製代碼
TCC適用於公司內部對一致性、實時性要求較高的業務場景,而本文咱們講解的「最大努力通知型事務」是爲解決跨網絡、跨服務之間的柔性事務的另外一種解決方案。數據庫
首先看一下最大努力通知型的流程圖,以下圖bash
咱們根據圖中的內容,逐步分析一下該方案的業務流程。網絡
1. 原理併發
首先闡述一下該方案的原理,根據圖中所示,框架
業務活動的主動方(通知發起方),在完成本地業務活動處理後,會向業務活動被動方發送消息【箭頭1】, 將業務執行結果通知給業務被動方【箭頭4】。這個過程容許消息丟失,若是發生丟失的狀況,服務主動方可以經過重試盡力實現雙方的數據一致性。此處的的重試就體現出了–最大努力 的特色。異步
而後是業務的被動方。業務被動方會暴露一個業務結果接收接口(或者叫回調接口也能夠)給業務主動方【箭頭4】,對收到的通知消息進行必要的校驗,校驗經過後執行本地業務,從而使業務達到閉環。分佈式
同時,因爲主動方對被動方的通知次數是有限的,即咱們不可能無限制的通知,所以業務活動主動方須要提供一個業務查詢補償接口供被動方使用【箭頭5】,被動方會根據定時策略,向業務活動的主動方發起查詢操做,從而對丟失的業務消息達到補償的目的。優化
整個過程當中,業務被動方暴露給主動方的通知接收接口 以及 業務主動方提供給被動方進行查詢操做的接口均須要實現冪等,這樣才能保證數據完整性不會被破壞,從而實現最終一致性。spa
2. 詳解code
接下來,咱們詳細展開對該方案的講解。
在這個方案中,咱們要求被動方的業務處理結果不能影響業務主動方的處理,雙方的職責是清晰的,例如:咱們接入支付寶的支付功能,我方的身份即業務被動方,而支付寶方則爲業務主動方。
我方接收到用戶的支付請求,等待用戶輸入支付密碼,用戶支付確認後,我方向支付寶發起支付請求,同步返回給用戶預支付結果。此時,用戶看到支付處理中。
當支付寶側執行轉帳完成以後(圖中的箭頭1),結果能夠是成功/失敗,總之主動方必定是在本地業務有肯定的執行結果後,纔會發起通知。
支付寶側會經過某種機制(猜測是圖中的消息隊列機制)將通知請求扔到通知消息服務中,通知發送核心業務消費通知消息,並記錄持久化消息到數據庫中,發送通知消息給我方。
我方支付回調接口收到支付完成通知後,會對參數進行簽名校驗,待簽名經過後,取出業務參數,對這筆支付訂單返回的結果進行後續操做(修改狀態爲下單完成併發貨或者修改成支付失敗,操做回滾/退款)。
這個過程理想狀態下是很快的,因爲支付寶側強大的處理能力,咱們幾乎感受不處處理中狀態,但整個過程確實是異步的過程。
【這裏給咱們的啓示之一即是,對於跨系統的交互,若是可以將同步的業務操做拆分爲異步過程,可以大幅度提升業務的靈活度及吞吐量。】
這裏存在一種廣泛的狀況,咱們的系統處理能力是有限的,在收到通知後未能及時的處理完成,這時,雙方會約定,若是收到通知且處理完成,業務被動方須要返回肯定某個狀態碼,如:「success」,不然認爲這次通知失敗。
這樣,只要咱們處理完成就返回「success」,主動方就不會繼續通知。不然,主動方會按照必定策略,好比「時間衰減策略」,對通知失敗的請求從持久層中取出,好比:24小時內,按照間隔1min、5min、10min、30min、1h、2h、5h、10h的方式,逐步拉大通知間隔,直到達到通知要求的時間窗口上限。這時,就須要被動法主動發起查詢。通常這種狀況不多,而這麼作的目的也是爲了使最近的請求更快的被通知回去,咱們認爲,時間越靠後,通知成功的可能性越少,由於大多數的通知請求在第一次通知發起時就返回了成功success。
PS:這裏還有一種措施,就是人工干預,重置通知位點。好比:若是達到最大通知次數依然沒有通知成功,那麼數據仍舊保存在通知庫裏面,運營人員在接收到商戶的重複通知需求的時候,經過人工的操做,從新重置通知次數,這樣消息就能夠從新通知了。
這種狀況每每是業務被動方未接入主動查詢致使的,不建議頻繁採用此方案,正常的流程時在開發階段就強烈要求被動方將通知接口及查詢接口均開發完成。
說多了都是淚,筆者曾經在工做中從事過一段時間商戶接入工做,就遇到過這種類型的商戶,常常要求咱們爲他們從新發起通知,對工做效率的影響真是肉眼可見的。
咱們說回正題,在異常狀況下,若是業務主動方在必定時間閾值內未能及時的發起通知,而做爲業務被動方的咱們又想及時獲取到業務結果,這時就須要業務被動方主動發起查詢,調用主動方暴露的查詢接口獲取業務結果,這裏通常採用定時做業輪詢,從而在業務上達到閉環, 最大可能的保證了數據的一致性。
3. 方案評價
4. 實現方式
從本文開始的圖中能夠看出,一般採用兩種方式實現
5. 如何優化
6. 小結
本文對分佈式事務解決方案的– 最大努力通知型 柔性解決方案進行了較爲詳細的講解,結合實例及筆者的工做經歷,對方案的各個細節展開講解,但願可以對讀者有所幫助。
後續筆者會着手開發一款分佈式事務的輪子,入手點將採用本文提到的模式,並最終達到基本可用。算是立了一個flag吧,完成以後會第一時間發文出來。(又一個有生之年系列)
到目前爲止,《我說分佈式事務》 系列就過半了,以後我會對可靠消息一致性方案進行講解,咱們不見不散。