基於可靠消息最終一致性的方案git
• 業務處理服務在業務事務提交前,向實時消息服務請求發送消息,實時消息服務只記錄消息數據,而不真正發送。業務處 理服務在業務事務提交後,向實時消息服務確認發送。只有在獲得確認發送指令後,實時消息服務才真正發送
• 業務處理服務在業務事務回滾後,向實時消息服務取消發送。消息狀態確認系統按期找到未確認發送或回滾發送的消息, 向業務處理服務詢問消息狀態,業務處理服務根據消息ID或消息內容肯定該消息是否有效
• 被動方的處理結果不影響主動方的處理結果, 被動方的消息處理操做是冪等操做
• 一次消息發送須要兩次請求,業務處理服務需實現消息狀態回查接口併發
設計圖: 設計
實現步驟:
1 .主動方(訂單服務)在業務事務提交前,向實時消息服務請求發送消息,實時消息服務只記
錄消息數據,而不真正發送。只將消息保存到DB,狀態status爲等待確認(WATING_CONFORM)。[步驟①,步驟a發送到mq的步驟還未執行,目前只是預發送(保存消息到DB)]blog
2 .主動方執行具體的業務(好比操做訂單相關的邏輯,步驟②),若是沒有問題,調用消息服務,發送消息到mq,而且更新消息表爲執行中狀態(SENDING)[步驟③]接口
3 . 消息服端監聽到消息後,調用被動方(會計服務)業務接口(好比操做會計憑證),若是成功(步驟d),調用消息服務確認系統,刪除存儲的消息[步驟e]事務
在步驟f有個消息恢復系統,主要處理兩種異常狀況:
i: 處理步驟②,執行具體業異常或者超時時,此時消息沒有發送到MQ,且DB中存儲的消息狀態仍是WATING_CONFORM,消息恢復子系統將這部分的數據拿出來從新發送,
此時須要注意,判斷冪等性,由於存在執行步驟②【好比操做訂單表】成功了,只是超時了,這個時間就須要判斷訂單是否是已經成功了,若是成功了就確認併發送消息,不然
直接刪除這條消息(由於確定是訂單業務失敗了,會回滾)
ii:處理3中,調用被動方業務失敗的狀況,此時失敗,就不會調用消息服務的確認系統,消息還存儲在DB中,此時狀態爲SENDING,經過消息恢復系統,將這部分的數據從新發送MQ【注意有最多發送次數,超過期,直接設置該消息死亡狀態】it
異常處理狀況:
1.主動方預發送消息(存儲DB)[步驟①] ,而後執行具體業務時(處理成功的狀況),超時致使異常,此時步驟③沒有執行,這時會經過消息恢復子系統從新處理(重發消息到mq,更改DB狀態SENDING)
若是業務執行失敗的狀況,會經過消息恢復子系統直接刪除DB裏的消息。[由於異常致使回滾,整個業務都是失敗的]
2. mq宕機,會通關消息回覆子系統重發消息
3. 消息服務端監聽後執行被動方業務失敗或者超時,此時會通關消息回覆子系統重發消息下載
目前本身搭建了一個環境,是開源的項目 reliable-message(提供服務) + reliable-message-samples(消費業務)這兩個項目組成了一個 中間消息服務請求
項目開源可在git 下載im