iT邦幫忙

2023 iThome 鐵人賽

DAY 17
0
Modern Web

30 天上手! PHP 微服務入門與開發系列 第 17

第十七章、微服務交易與 Saga 設計模式 - PHP 微服務入門與開發

  • 分享至 

  • xImage
  •  

在微服務架構中,每個服務都是獨立且自治的,每個服務都有自己的資料庫系統並維護著自身的資料庫交易實作。當業務流程需要跨多個服務時,便會面臨分散式交易(Distributed Transactions)的難題。分散式交易是指在多個獨立的系統或服務中進行的交易,這些交易需要保證要麼全部成功,要麼全部失敗,以保證資料的一致性。

然而,由於微服務間的通訊往往不是不可靠的,並且各個服務之間可能存在網路延遲和故障,因此在微服務架構中實現分散式交易是具有挑戰性的。這些挑戰不僅來自於微服務間的通信不可靠和網絡延遲,還來自於系統的複雜性和不確定性。以本系列文章的例子來看,在建立訂單的業務邏輯中由許多微服務組成,可能需要涉及到多個微服務的相互配合。

首先,訂單服務需要創建一個新訂單;其次,庫存服務需要檢查並更新庫存;最後,支付服務需要處理支付交易。在這個過程中,如果任何一個步驟失敗,都需要能夠恢復到交易開始之前的狀態,以保證資料的一致性。

而分散式交易有幾種常用解決方案,如:2PC(Two-Phase Commit)、3PC(Three-Phase Commit)和 Saga 模式。

二階段提交(Two-phase Commit)

二階段提交是一種分散式系統中確保交易原子性的協議,它將交易的提交過程分為兩個階段,以確保所有參與的節點都能達成一致。各個節點只負責執行服務內的本地交易。分散式交易將分為兩階段執行:

  1. 投票階段:

    • 交易協調器(Coordinator)向所有參與者(Participants)發送 Prepare 訊息,請求它們準備進行交易。
    • 參與者接收到 Prepare 訊息後,執行交易操作,但不立即完成。如果操作成功,它們會鎖定參與交易的資源,防止其他操作干擾,並向協調器回覆「準備好了」(Ready)的訊息。如果操作失敗,它們會向協調器回覆「失敗」(Fail)的訊息。
  2. 提交階段:

    • 如果協調器收到了所有參與者的「準備好了」回覆,它會向所有參與者發送 Commit 訊息,要求它們完成交易。
    • 參與者接收到 Commit 訊息後,將立刻完成交易並釋放資源,並向協調器回覆「已提交」(Committed)的訊息。
    • 當協調器在第一階段收到了任何「失敗」回覆,或者在第二階段有參與者未能成功提交,它會向所有參與者發送 Abort 訊息,要求它們還原(Rollback)交易。

三階段提交(Three-Phase Commit)

三階段提交是二階段提交協議的一個改進版本,它透過加入一個額外的階段來減少系統的阻塞和提高分散式交易的效率:

  1. 準備階段 (Pre-Commit Phase):

    • 交易協調器向所有參與節點發送 CanCommit 訊息,詢問它們是否可以提交交易。
    • 參與節點執行交易操作,但不提交。如果操作成功,它們回覆 Yes 給協調器;如果操作失敗,它們回覆 No 給協調器。
  2. 提交階段 (Commit Phase):

  • 如果協調器從所有參與節點收到的回覆都是 Yes,它會進入提交階段,向所有參與節點發送 PreCommit 訊息,並等待它們的確認。
    • 參與節點收到 PreCommit 訊息後,節點會鎖定交易所需的資源以防止其他操作干擾,並向協調器回覆 Ack。如果在此階段有任何節點回覆 Abort,或者協調器在指定時間內未收到所有的 Ack 訊息,那麼它就會向所有節點發送 Abort 進行還原。
  1. 最終提交階段 (Final Commit Phase):
    • 協調器在收到所有節點的 Ack 訊息後,向它們發送 DoCommit 訊息,指示它們完成交易。
    • 參與節點收到 DoCommit 訊息後,將立刻完成交易並釋放資源,並向協調器回覆 Done 訊息。如果任何節點在此階段失敗,協調器將會指揮節點進行還原。

三階段提交透過增加一個額外的 Pre-Commit 階段,嘗試減少因網絡分割或節點故障而導致的系統阻塞,並提供更高的效率和可靠性。

Saga 模式

Saga 模式[1]是一種非常適合於微服務架構的分散式交易解決方案,它將長期的交易拆分為小步驟的交易,每個交易都有一個相應的補償交易,用於在某個步驟失敗時還原之前的改變。在微服務架構中,我們有兩種開發模式可以實現 Saga 分別是服務編排(Choreography)與服務協作(Orchestration)模式。

服務編排與服務協作的差異可以至第二章-微服務與它們的溝通管道 參閱詳細介紹。

  • 服務編排型 Saga
    在編排模式中,每個服務都知道接下來要做什麼,在完成本地交易後通知下一個服務。這是一種去中心化的方法,每個服務都獨立地參與協調,透過事件來觸發接下來的行為,使用這個方式開發的微服務系統將能夠減少耦合。但以這個模式實作的系統較難以傳達與追蹤交易的整體流程。
  • 服務協作型 Saga
    在協作模式中,將會有中心化的協作器負責管理交易的執行流程。協作器知道每個步驟何時執行,並通知相應的服務來執行交易或補償。此種模式將易於理解與追蹤交易流程,但協作器若發生故障將可能影響交易流程,並容易因為高負載而成為系統瓶頸。

在 Saga 模式中交易由交易序列(Transaction Sequence)所組成,如:T1, T2, …, Tn。在交易序列中的每一個步驟(Step)將是服務內的資料庫交易。Saga在補償處理的機制上,在定義交易序列(Transaction Sequence)的同時,也會定義補償序列(Compensate Sequence),如:C1, C2, …, Cn。當交易步驟執行失敗時,Saga 機制將會依照宣告好的補償步驟往回進行補償。

相對於其他模式,Saga 提供了一種更為靈活的解決方案。協作型的 Saga 的中央協作器將負責保障所有交易內容按照預定的順序執行,並在出現錯誤時觸發相應的補償交易,這種模式大大降低了系統的復雜度。

而 Saga 在資料庫的 ACID 理論中僅滿足 ACD 並不保障 I(隔離性),因此我們可能會發生下列的交易異常:

  • Saga 在自己的更新流程執行時,並不發現另一個 Saga 對資料進行改變,進而直些覆蓋更新
  • Saga 可能會取得某個尚未完成整體流程的 Saga 所做的改變
  • 某個 Saga 所需的資料在執行的週期發生改變,以至於在不同的步驟讀取時是不同的內容

我們可以以下列策略應對問題:

  • 在應用程式的層級替敏感資源加入鎖定邏輯
  • 在業務操作的當下讀取最新資料,並確保在更新時資料還是當初讀取時的樣子
  • 在較長的交易中可以先凍結部分被扣除的欄位,直到交易完成
  • 僅在低商業風險的業務需求使用 Saga

資料庫高可用性理論 BASE

  2008年,大型電子商務公司eBay架構師 Pritchett 提出了新的資料庫理論「BASE」[2]。相較於ACID強制保持一致性,BASE更著重於接受資料庫一致性將處於不斷變化的狀態,同時也能更易於管理資料庫,達到ACID無法獲得的擴充性。BASE為以下幾個特性組成,分別是:

  • 基本可用性(Basically Available):即使在節點故障時,系統也能保證資料某些程度的可用性。資料可能是舊的,但仍能給予與接受響應。
  • 軟性狀態(Soft State):資料處於不斷變化的狀態,可以容忍系統中的臨時不一致,並允許系統在沒有外部輸入的情況下,透過內部過程來改變其狀態。
  • 最終一致性(Eventual Consistency):資料最終會在所有節點和所有資料庫保持一致,最終會達成某種保證狀態。

BASE理論反映了在分散式環境中實現高可用性和擴展性的需求,它放寬了一致性的要求,以實現更高的可用性。這是分散式系統和微服務架構中常見的一種取舍。

結語

總的來說,Saga 設計模式為微服務架構中的分散式交易提供了一個較為實用和靈活的解決方案。它允許系統在出現錯誤時進行有效的補償,從而保證了資料的一致性,並降低了復雜的協調和通訊開銷;然而,它也帶來了一些挑戰,例如可能的交易異常和必要的補償邏輯設計。在採用Saga模式時,開發人員需要仔細考慮和設計每個微服務的交易和補償機制,以確保系統的健壯性和可靠性。

在實際應用中,可能會根據具體的系統架構和業務需求,將 Saga 模式與其他分散式交易解決方案(如2PC或3PC)結合使用,以達到最佳的效果。

參考文獻

[1] Hector Garcia-Molina and Kenneth Salem, "Sagas", ACM Sigmod Record, vol. 16, no. 3, pp. 249-259, 1987.
[2] D. Pritchett, " BASE: An Acid Alternative: In partitioned databases, trading some consistency for availability can lead to dramatic improvements in scalability," Queue, vol. 6, no. 3, pp. 48–55, May 2008.


上一篇
第十六章、Anser-Orchestration:建立訂單,與三個微服務溝通的協作器 - PHP 微服務入門與開發
下一篇
第十八章、微服務自身的交易與安全的資源操作 - PHP 微服務入門與開發
系列文
30 天上手! PHP 微服務入門與開發30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言