微服務下的資料一致性思考

ForestXie發表於2017-06-01

之前講到了資料庫層快取層的改造思路,而對於業務層的改造,採用了集中式服務轉微服務的架構方案。既然是微服務,就意味著面臨大量的服務間的內部呼叫及服務依賴,這就意味著,如果一次請求的呼叫涉及到兩個或多個微服務之間的呼叫,恰好有下游的微服務呼叫失敗,我們就必須要考慮到回滾及服務間保證資料一致性的問題。所以,今天我將列出可能出現的失敗情況及對應的解決方案,希望對大家正在做微服務改造的團隊有所幫助。

首先,我們對微服務間呼叫做一個分類:

  1. 服務間沒有直接依賴,採用非同步化呼叫,上游服務完成後,發一個訊息非同步通知下游服務,下游服務成功與否對上游服務沒有影響。

  2. 上游服務弱依賴於某個下游服務的處理結果,可降級。降級時可以不返回這部分的資料。同步呼叫降級時轉為非同步。

  3. 上下游微服務強依賴,上游服務依賴於下游服務的返回或者回撥,下游必須正常執行,如果下游服務失敗了,本次請求判定為失敗。

服務間純非同步呼叫,需保證冪等性和佇列重試機制

對於Case1, 只需要考慮2點:冪等性和訊息佇列重試機制,冪等性意味著,重複訊息不會對下游服務的結果產生任何影響;訊息佇列重試機制保證了,訊息本身不會出現丟失,即便訊息佇列在發給下游佇列前掛掉了,重啟後,能繼續傳送對應的訊息。

上下游同步執行失敗,通過訊息執行非同步呼叫

微服務下的資料一致性思考

對於Case2, 採用的方案如下圖所示,主服務依賴於A,B,C 三個下游服務,同步呼叫過程中,服務C呼叫失敗。由於服務C不是強依賴,我們便可以給訊息佇列傳送一條訊息,保證主服務可以正常返回,同時保證服務C能繼續被執行,保證資料的一致性。

採用TCC進行提交與回滾,保證資料的一致性

Case3是服務間呼叫最嚴格的情況,意味著如果下游服務中有一個服務呼叫失敗,上下游的所有服務必須回滾。意味著服務間必須保證同一個事務。業界公認的一個解決方案就是 TCC (Try-Confirm-Cancel) 模式:

  1. 主業務服務分別呼叫下游業務執行try操作,並在活動管理器中登記所有下游服務。當所有下游微服務的try操作都呼叫成功,或者某個下游微業務服務的try操作失敗。

  2. 業務活動管理器根據第1步的執行結果來執行confirm或cancel操作。如果之前所有try操作都成功,則活動管理器呼叫所有下游微業務,執行confirm操作。否則呼叫所有下游微服務的cancel操作。

  3. 如果第2步,執行confirm或concel操作出現失敗,活動管理器會啟動重試機制,保證所有微服務最終提交或者回滾操作成功。

    微服務下的資料一致性思考


小結

上文對微服務間呼叫的3種情況的資料一致性方案做了說明:

1. 確保介面冪等性,訊息佇列具備重試機制,實際上幾乎現在所有的MQ都支援重試。

2. 服務呼叫同步轉非同步,確保上游服務成功執行,並保證服務間的資料一致性。

3. 利用TCC方案解決服務間呼叫強依賴的資料一致性。

掃描二維碼或手動搜尋微信公眾號: ForestNotes

歡迎轉載,帶上以下二維碼即可

微服務下的資料一致性思考

相關文章