基於本地訊息表的分散式事務
阿新 • • 發佈:2021-10-29
分散式事務:
在微服務架構下,一個大的操作往往由不同的小操作組成,並且這些小操作分佈在不同的伺服器上,對應不同的資料庫,分散式事務需要保證這些小操作要麼全部成功要麼全部失敗,即保證資料一致性。
例如一個支付業務:
在某些業務場景下,使用者發起支付申請,只要申請成功,就可以做其他事情。
正常流程:
- 系統接受到申請後,支付申請服務經過一些業務校驗,先落支付申請庫
- 再將訊息傳送至MQ
- 支付交易服務監聽到MQ訊息進行進一步的處理落庫。
但此時也有一些新的問題出現:
- 若支付申請服務完成邏輯後,在投遞訊息到MQ中介軟體的過程中由於網路抖動等原因,沒有投遞到MQ中導致訊息丟失了怎麼辦?
- MQ接收到訊息後,由於內部原因導致訊息丟失了怎麼辦?
- 支付交易服務在監聽訊息的過程中,由於網路原因沒有接收到訊息或消費過程中遇到異常,此時也會導致訊息丟失,怎麼辦?
- 由於MQ元件問題,導致支付交易服務重複消費怎麼辦?
針對前三種問題,都是訊息丟失導致的,可以採用本地訊息表+定時任務來解決。
針對第四種問題,是因為重複消費導致的,就需要支付交易服務做好冪等防重。
增加本地訊息表+定時任務:
此時資料流程如下:
正向流程:
- 系統接受到申請後,在同一本地事務寫入本地訊息表和業務表,本地訊息表狀態為處理中,再發送訊息到MQ
- 支付交易服務監聽到訊息後,進行一些邏輯之後,將結果傳送至MQ
- 支付申請監聽到處理結果,更新本地訊息表的狀態,處理結束
補償措施:
- 假如訊息丟失,還有定時任務定時掃描本地訊息表中狀態為處理中的資料,進行下發,後續處理和正向流程的2、3一致
特點:
- 最大努力通知
- 最終一致性
注意:
- 真實業務處理的狀態可能會有多種,因此需要明確哪種狀態需要定時任務補償
- 假如某條單據一直無法處理結束,定時任務也不能無限制下發,所以本地訊息表需要增加輪次的概念,重試多少次後告警,人工介入處理
- 因為MQ和定時任務的存在,難免會出現重複請求,因此下游要做好冪等防重,否則會出大問題