1. 程式人生 > >分散式事務(1)訊息傳送一致性解決方案

分散式事務(1)訊息傳送一致性解決方案

訊息傳送一致性 是指產生訊息的業務動作與訊息傳送的一致。(如果業務操作成功,那麼由這個業務操作所產生的訊息一定要成功投遞出去,否則就丟訊息) 訊息傳送一致性如何保障: 場景: 1.業務處理成功,執行傳送訊息的時候 應用故障,導致沒有傳送訊息(後續服務沒有收到訊息處理業務,結果資料不一致) 2.業務處理成功,執行傳送訊息的時候,訊息系統(MQ)故障,導致訊息傳送失敗(後續服務沒有收到訊息處理業務,結果資料不一致) 解決方案: 1.主動方應用先把訊息發給訊息中介軟體,訊息狀態標記為“待確認” 2.訊息中介軟體收到訊息後,把訊息持久化到訊息儲存中,但並不向被動方應用投遞訊息 3.訊息中介軟體返回訊息持久化結果(成功/失敗),主動方應用根據返回結果進行判斷如何進行業務操作處理 a:失敗,放棄業務操作處理,結束(必要時向上層返回失敗結果) b:成功,執行業務操作處理 4.業務操作完成後,把業務操作結果(成功/失敗)傳送給訊息中介軟體 5.訊息中介軟體收到業務操作結果後,根據業務結果進行處理 a:失敗:刪除訊息儲存的訊息,結束 b:成功:更新訊息儲存的訊息狀態為“待發送(可傳送)”,緊接著執行訊息投遞 6.確保了主動方應用業務處理成功就一定會發送訊息 7.被動方應用監聽並接收“待發送狀態的訊息”執行業務處理 8.業務處理完成後向訊息中介軟體傳送ACK確認,確認訊息已經收到(訊息中介軟體將從佇列中刪除該訊息)
訊息傳送一致性流程中的異常點 異常情況: 主動方 1.預傳送訊息失敗: 訊息未進行儲存,業務操作未執行(可能的原因:主動方應用、網路、訊息中介軟體、訊息儲存)【一致】 2.預傳送訊息後,主動方應用沒有收到返回訊息儲存的結果: a:訊息未進儲存,業務操作未執行【一致】 b:訊息已進儲存(待確認),業務操作未執行【不一致:待確認訊息已儲存,但是業務卻沒執行】 3.收到訊息儲存成功的返回結果,但未執行業務操作就失敗 訊息已進儲存(待確認),業務操作未執行【不一致:待確認訊息已儲存,但是業務卻沒執行】 訊息中介軟體 1.訊息中介軟體沒有收到主動方應用的業務操作處理結果 a:訊息已進儲存(待確認),業務操作未執行成功(或業務操作出錯回滾了)【不一致:待確認訊息已儲存,但是業務失敗】
b:訊息已進儲存(待確認),業務操作成功(主動方網路中斷)【不一致:待確認訊息已儲存,但是業務操作成功,但是沒有修改訊息狀態為待發送】 2.訊息中介軟體收到業務操作結果(成功/失敗),但處理訊息儲存中的訊息狀態失敗 a:訊息已進儲存(待確認),業務操作未執行成功(或業務操作出錯回滾了),告知訊息中介軟體失敗(MQ操作訊息狀態失敗)【不一致:業務失敗,未刪除訊息】 b:訊息已進儲存(待確認),業務操作成功,告知訊息中介軟體成功(MQ更新訊息狀態失敗)【不一致:業務成功,訊息狀態未更新成待發送】 總結: 1.訊息未進儲存,業務操作未執行【一致】 2.訊息已進儲存(狀態待確認)業務操作未執行或失敗【不一致】
異常解決方案:刪除訊息 3.訊息已進儲存(狀態待確認)業務操作成功【不一致】 異常解決方案:更新訊息狀態 異常處理還是會有異常 解決方案:訊息持久化,建立定時任務查詢訊息中介軟體查詢狀態為“待確認”的訊息呼叫主動方應用的業務操作結果查詢介面,返回業務處理結果(成功/失敗)去更新訊息狀態 被動方 訊息重複傳送的原因 1.被動方應用接收到訊息,業務處理完成後應用出問題,訊息中介軟體不知道訊息處理結果,會重新投遞訊息 2.被動方應用接收到訊息,業務處理完成後網路出問題,訊息中介軟體不知道訊息處理結果,會重新投遞訊息 3.被動方應用接收到訊息,業務處理時間過長,訊息中介軟體因訊息超時未確認,會再次投遞訊息 4.被動方應用接收到訊息,業務處理完成,訊息中介軟體問題導致收不到訊息處理結果,訊息會重新投遞 5.被動方應用接收到訊息,業務處理完成,訊息中介軟體收到了訊息處理結果,但由於訊息儲存故障導致訊息沒能確認,訊息會再次投遞 總結:訊息消費過程中產生訊息重複傳送主要是因為訊息接收者成功處理完訊息後,訊息中介軟體沒能及時更新訊息投遞狀態(也就是訊息沒能及時ACK確認)導致的 解決方案: 訊息重複傳送無法解決,通過被動方應用實現冪等性設計(任意多次執行所產生的影響均與一次執行的影響相同) 1.通過業務操作本身實現冪等性 2.系統快取所有請求與處理結果 檢測到重複請求後,自動返回之前的處理結果 極端情況: 訊息重發也得有次數限制,要不然就變成了死迴圈,對於超過重發限制的訊息,進入DLQ(死亡佇列),等待人工干預或延後定期處理
實現方式: 1.本地訊息服務 1.在主動方應用業務操作中,用一個本地事務將業務處理和訊息確認資料存放在本地庫中,確保業務完成 本地一定有一條“待確認的訊息資料” 2.主動方應用業務處理成功後,傳送訊息至MQ中 3.被動方應用採用自動ACK確認方式,處理業務(需加冪等性設計) 4.業務處理成功後呼叫主動方訊息確認介面(或再加一個訊息確認的MQ,只是業務會相對更復雜),修改訊息資料狀態,完成整體流程 5.訊息恢復系統定時輪詢一段時間未確認的訊息資料,從新放置再MQ中繼續消費 優點: 1.訊息資料的可靠性不依賴於MQ,弱化了多MQ的依賴 2.方案輕量級,容易實現 缺點: 1.業務和訊息耦合性高,不可共用 2.訊息資料與業務資料同庫,佔用資源 3.業務系統在使用關係型資料庫的情況下,訊息服務效能會受到關係型資料庫併發效能的侷限 2.獨立訊息服務 1.主動方應用系統呼叫訊息服務系統預傳送訊息 2.獲得返回結果後處理業務操作,傳送結果告知訊息服務系統 3.訊息服務系統根據業務處理結果(成功/失敗)修改訊息狀態為“待發送” 異常情況: 業務處理成功,但是與訊息系統確認訊息狀態失敗 通過訊息狀態確認子系統定時輪詢未確認的訊息去主動請求主動方應用獲得業務處理結果更新訊息狀態 4.被動方系統接收訊息,ACK確認刪除MQ中的訊息,處理業務邏輯完成後 5.呼叫訊息系統確認訊息已被成功消費(更新訊息狀態或刪除訊息記錄) 異常情況: 業務處理成功後沒有修改成功訊息系統此條訊息被成功消費狀態 通過訊息恢復子系統定時輪詢成功消費的訊息從新放到MQ佇列中去重做直到成功 被動方採用冪等性設計保證多次消費的結果一致性 優點: 1.訊息服務獨立部署,獨立維護、獨立伸縮 2.訊息儲存可以按需選擇不同的資料庫來整合實現(關係型資料庫或者nosql) 3.可複用,可以被相同的使用場景共用 4.訊息資料的可靠性不依賴於MQ,弱化了多MQ的依賴 5.降低了業務系統和訊息系統間的耦合,有利於系統的擴充套件維護 缺點: 1.一次訊息傳送需要兩次請求,時效性偏低一點 2.主動方應用系統需要實現業務操作狀態校驗查詢介面 訊息狀態確認子系統設計 1.系統集成了訊息系統查詢“未確認”資料介面服務,主動方查詢業務狀態介面服務 2.訊息系統查詢“未確認“資料介面,查詢條件: 狀態“未確認“ 查詢升序(ASC,先處理最早的資料) 指定固定數量(防止資料量過多一次查詢出來) 並且訊息存放時間大於一定時間(防止拿到新資料) 3.遍歷拿到的“未確認“訊息資料,呼叫主動方查詢業務狀態介面查詢業務狀態或者未生成業務資料 a)如果業務狀態為成功,則修改訊息狀態為“待發送” b)如果業務狀態為失敗或者就沒執行業務,則刪除訊息 訊息恢復子系統設計 1.系統集成了訊息系統查詢“未消費“資料介面服務 2.訊息系統查詢“未消費“資料介面,查詢條件: 狀態“未消費“ 查詢升序(ASC,先處理最早的資料) 指定固定數量(防止資料量過多一次查詢出來) 並且訊息存放時間大於一定時間(防止拿到新資料) 未死亡的訊息(重試多次後還失敗的訊息會放入死亡佇列) 3.遍歷拿到的“未消費“訊息資料 a)判斷訊息重試次數是否達到最多重試次數,如果達到則標記此訊息死亡(防止訊息一直重試) b)根據訊息重試次數判斷是否達到了訊息間隔 如第1次失敗1分鐘後就可以嘗試重試,第5次失敗則可以30分鐘後再嘗試,第6次就標記為死亡 c)重發訊息 訊息服務子系統設計 1.儲存預傳送訊息 2.確定併發送訊息 3.查詢確認超時的訊息(一直處於“未傳送”狀態的訊息) 4.確認已被成功消費訊息 5.查詢消費確認超時的訊息(一直處於“未消費”狀態的訊息) 6.刪除訊息 實時訊息服務子系統設計(操作MQ) 1.修改mq重試次數為1或者0,將重試的機制交給訊息恢復子系統去處理,減少頻繁短時間內多次重試帶來的效率問題