假設我們的業務規則說,當用戶下訂單時,如果產品的價格在使用者的信用限額/餘額之內,則訂單將被履行。否則將無法實現。看起來真的很簡單。
這在整體/單體應用中非常容易實現。整個工作流程可以視為1個單事務。當所有內容都在單個數據庫中時,提交/回滾很容易。對於具有多個數據庫的分散式系統,這將非常複雜!首先讓我們看一下我們的架構,看看如何實現它。
我們有一個帶有其自己的資料庫的訂單服務,該資料庫負責訂單管理。同樣,我們還提供付款服務,負責管理付款。因此,訂購服務接收到該請求,並與付款服務核對使用者是否有餘額。如果付款服務響應“確定”,則訂購服務將完成訂單,付款服務將扣除付款。否則,訂單服務將取消訂單。對於非常簡單的業務要求,這裡我們必須透過網路傳送多個請求。
在傳統的系統設計方法中,訂購服務僅傳送HTTP請求以獲取有關使用者信用餘額的資訊。這種方法的問題是訂單服務假定付款服務將始終啟動並執行。付款服務上的任何網路問題或效能問題都將傳播到訂購服務。這可能會導致不良的使用者體驗,並且我們也可能會損失收入。
讓我們看看如何透過使用事件溯源的Saga模式來處理鬆散耦合的分散式系統中的事務。
跨越多個微服務的每個業務交易事務都被分成特定於微服務的本地交易事務,並按順序執行它們以完成業務工作流程。它被稱為Saga。它可以透過兩種方式實現。
事件溯源
在這種方法中,對應用程式狀態的每次更改都被捕獲為一個事件。此事件儲存在資料庫中(出於跟蹤目的),並且還發布在事件匯流排中,供其他方使用。
訂單服務收到建立新訂單的命令。該請求將作為訂單建立的事件進行處理並引發。這裡要注意的幾件事。
訂單建立事件基本上會通知新訂單請求已收到,並由訂單服務保持為“待處理”狀態。尚未實現。事件物件將始終以過去時態命名,因為它已經發生了!現在,付款服務可能會對收聽這些事件以及批准/拒絕付款感興趣。即使這些也可以視為事件。付款批准/拒絕事件。訂單服務可能會監聽這些事件,並履行/取消其最初收到的訂單請求。
這種方法有很多優點。
沒有服務依賴性。付款服務不必始終保持正常執行。松耦合水平縮放容錯業務工作流的實現如下所示。
order-services收到新訂單的POST請求它將訂單請求以ORDER_CREATED狀態放置在資料庫中並引發一個事件支付服務監聽事件,確認信用額度order-service根據信用保留狀態完成訂單或拒絕訂單。在這裡有一個完整的工作專案。您可以克隆程式碼並執行以在此處進行演示。確保您已建立並執行本地kafka群集。您可以使用此docker-compose檔案 執行本地kafka叢集。
狀態更新
一旦訂單服務完成訂單並引發另一個事件。運送服務會監聽事件,並負責將包裝和運送到給定的使用者地址。訂單服務可能會再次監聽那些事件,從而將其資料庫更新為order_shipped狀態。
正如我們前面提到的,提交/回滾跨多個微服務的事務非常具有挑戰性。每個服務都應具有事件處理程式,以便針對它正在偵聽的每個事件來提交/回滾事務以維護資料一致性!