分散式事物----可靠訊息一致性方案
基於可靠訊息最終一致性的方案
• 業務處理服務在業務事務提交前,向實時訊息服務請求傳送訊息,實時訊息服務只記錄訊息資料,而不真正傳送。業務處 理服務在業務事務提交後,向實時訊息服務確認傳送。只有在得到確認傳送指令後,實時訊息服務才真正傳送
• 業務處理服務在業務事務回滾後,向實時訊息服務取消傳送。訊息狀態確認系統定期找到未確認傳送或回滾傳送的訊息, 向業務處理服務詢問訊息狀態,業務處理服務根據訊息ID或訊息內容確定該訊息是否有效
• 被動方的處理結果不影響主動方的處理結果, 被動方的訊息處理操作是冪等操作
• 一次訊息傳送需要兩次請求,業務處理服務需實現訊息狀態回查介面
設計圖:
實現步驟:
1 .主動方(訂單服務)在業務事務提交前,向實時訊息服務請求傳送訊息,實時訊息服務只記
錄訊息資料,而不真正傳送。只將訊息儲存到DB,狀態status為等待確認(WATING_CONFORM)。[步驟①,步驟a傳送到mq的步驟還未執行,目前只是預傳送(儲存訊息到DB)]
2 .主動方執行具體的業務(比如操作訂單相關的邏輯,步驟②),如果沒有問題,呼叫訊息服務,傳送訊息到mq,並且更新訊息表為執行中狀態(SENDING)[步驟③]
3 . 訊息服端監聽到訊息後,呼叫被動方(會計服務)業務介面(比如操作會計憑證),如果成功(步驟d),呼叫訊息服務確認系統,刪除儲存的訊息[步驟e]
在步驟f有個訊息恢復系統,主要處理兩種異常情況:
i: 處理步驟②,執行具體業異常或者超時時,此時訊息沒有傳送到MQ,且DB中儲存的訊息狀態還是WATING_CONFORM,訊息恢復子系統將這部分的資料拿出來重新發送,
此時需要注意,判斷冪等性,因為存在執行步驟②【比如操作訂單表】成功了,只是超時了,這個時間就需要判斷訂單是不是已經成功了,如果成功了就確認併發送訊息,否則
直接刪除這條訊息(因為肯定是訂單業務失敗了,會回滾)
ii:處理3中,呼叫被動方業務失敗的情況,此時失敗,就不會呼叫訊息服務的確認系統,訊息還儲存在DB中,此時狀態為SENDING,通過訊息恢復系統,將這部分的資料重新發送MQ【注意有最大發送次數,超過時,直接設定該訊息死亡狀態】
異常處理情況:
1.主動方預傳送訊息(儲存DB)[步驟①] ,然後執行具體業務時(處理成功的情況),超時導致異常,此時步驟③沒有執行,這時會通過訊息恢復子系統重新處理(重發訊息到mq,更改DB狀態SENDING)
如果業務執行失敗的情況,會通過訊息恢復子系統直接刪除DB裡的訊息。[因為異常導致回滾,整個業務都是失敗的]
2. mq宕機,會通關訊息回覆子系統重發訊息
3. 訊息服務端監聽後執行被動方業務失敗或者超時,此時會通關訊息回覆子系統