支付系統 DDD 重構設想
前言
領域驅動設計(DDD)和微服務架構是兩種在架構設計領域廣泛應用的方法。它們都旨在通過從業務視角分離應用系統的複雜度來提高系統響應力。
這篇文章將詳細介紹 DDD 的基本概念、名詞解釋、架構模式以及如何對現有系統進行重構。
什麼是 DDD(領域驅動設計)
DDD 是一種架構設計方法,強調從業務出發合理劃分領域邊界,調整現有架構並優化代碼,以實現演進式架構。
其核心理念是通過領域拆分解決複雜業務問題,控制和管理業務複雜性。
定義領域
領域指特定的問題域,用來限定業務邊界。領域模型是對業務領域中概念、規則和行爲的抽象,通常由領域專家和開發人員共同創建。
例如,交易領域限制所有交易相關業務的範疇。
實際上,平臺支付系統並不僅僅包含支付領域,相對的,它實際上是一個交易系統,支付只是交易的一部分,以下我們統一使用交易 xxx 來稱呼。
領域模型
領域模型反映了業務領域中的實體、值對象、聚合、工廠和存儲庫等,它是領域專家和開發人員共同構建的一個抽象模型,用來描述和解決業務問題。
限界上下文
限界上下文定義了業務領域中的邊界,確保在該邊界內使用統一的術語和規則。不同限界上下文之間可以使用相同的術語表達不同的業務含義,從而實現獨立的業務邏輯和數據模型。
例子
在交易業務中,訂單和支付是兩個緊密聯繫但邏輯上相互獨立的領域。
通過限界上下文,可以將交易領域拆分爲訂單中心和支付中心兩個子域。
集成方式
限界上下文之間可以通過多種方式集成,以實現系統的整體功能。其中常見的集成方式有:
-
事件驅動(Event-Driven):通過事件進行通信,一個上下文發佈事件,另一個上下文訂閱並處理事件。
-
請求響應(Request-Response):通過請求和響應進行通信,一個上下文發送請求,另一個上下文返回響應。
-
共享數據庫(Shared Database):多個上下文共享同一個數據庫進行通信。
-
REST API:一個上下文通過發送 RESTful 請求,另一個上下文返回響應。
集成示例
例如,在支付完成後,可以通過發佈支付成功事件,觸發訂單中心完成支付的相關流程,像發貨、推送統計等。
架構演進
軟件架構從單機、集中式到分佈式微服務架構經歷了三個階段的演進,每個階段都以提高系統響應力爲目標,通過分離複雜度來實現業務優化。
架構模式
DDD 架構模式有多種,每種都有其優缺點和適用場景:
分層架構
分層架構通過將系統劃分爲不同層次,實現清晰的職責分離和松耦合:
-
接口層:與用戶交互,定義 API 接口。
應用層:協調系統各部分,完成業務編排。
領域層:定義和實現業務邏輯,是 DDD 的核心。
防腐層:隔離外部系統,保護領域模型。
基礎設施層:提供必要的技術支持,如數據存儲和消息隊列。
優勢
-
職責清晰
易於理解和實現
支持良好的擴展性
劣勢
- 可能導致層次過多,複雜度增加
CQRS 架構
CQRS 架構通過分離讀寫操作,優化系統性能:
-
命令模型:處理寫操作。
查詢模型:處理讀操作。
優勢
-
利於優化讀寫性能
容易擴展和維護
劣勢
- 實現複雜度較高,需考慮命令和查詢的同步問題
事件驅動架構(EDA)
事件驅動架構通過事件來驅動系統行爲,實現松耦合和高併發:
-
事件生產者:發佈事件。
事件消費者:訂閱和處理事件。
優勢
-
提高系統松耦合性
支持高併發
實現異步處理
劣勢
- 需處理事件丟失或重複消費的問題
微服務架構
微服務架構將系統劃分爲多個小型服務,每個服務有獨立職責,圍繞業務領域構建:
-
服務定義和發現:確保服務可獨立部署和運行。
負載均衡和容錯:提高系統可用性。
優勢
-
獨立部署和擴展
支持多技術棧
更容易管理和維護
劣勢
- 需處理服務間通信、服務發現和負載均衡等問題
重構設想
背景
目前交易系統的支付領域和訂單領域耦合度高,存在職責不清晰、維護性和擴展性不佳的問題。
現存問題
-
職責不清晰:交易邏輯分散於多個模塊,易與其他業務邏輯耦合。
可維護性不高:事務腳本式編碼導致業務規則散落,影響閱讀和維護。
可擴展性不高:歷史技術債務多,新功能支持需改動多個關鍵鏈路。
重構目標
-
獨立管理交易鏈路核心業務:拆分和遷移現有業務邏輯,實現核心業務內聚。
提高系統可維護性:通過 DDD 拆分業務子域,減少組件升級對業務邏輯的影響。
提高業務擴展性:利用設計模式和擴展點,區分不穩定節點和固定節點。
領域劃分
合理劃分領域
在進行領域劃分時,需要考慮以下幾點:
-
業務邏輯清晰:確保每個領域內的業務邏輯獨立且清晰,使其不與其他領域業務邏輯混淆。通過業務用例的分析,識別出各個子域中的概念、流程和規則。
-
領域專家協作:領域模型應由領域專家和開發人員共同創建,反映實際業務情況。通過領域工作坊等活動,確保領域專家的知識得到充分應用。
-
避免過度劃分:儘量避免過度細分領域,以免增加系統複雜度。適度劃分有助於管理領域邊界,並有助於日後的維護和擴展。
-
業務變化靈活應對:領域劃分應當是靈活的,可以根據業務需求變化進行調整和優化。選擇適合的設計模式(如策略模式、狀態模式等)來處理業務變化。
-
聚合關係:根據實體間的聚合關係劃分子領域,確保領域內高度內聚和外部低耦合。識別業務中的聚合根,確定其邊界和生命週期。
步驟示例
-
識別業務域:通過訪談業務專家、分析業務流程和用例,識別出系統中的主要業務域。
劃分子域:識別業務中的核心域(關鍵業務)、支撐域(輔助業務)和通用域(共享業務)。
-
定義領域模型:與領域專家合作,定義領域中的實體、值對象、聚合根、工廠和存儲庫。
確定限界上下文:根據業務邊界確定限界上下文,清晰定義每個上下文的職責和接口。
-
設計交互模式:選擇適合的交互模式(事件驅動、請求響應等)實現限界上下文間的通信。
劃分實踐
核心域
-
支付中心:負責玩家支付行爲和渠道管理。
訂單中心:負責訂單生命週期管理和交易處理。
通用域
-
商品域:負責遊戲商品信息的管理。
優惠域:負責優惠券、積分抵扣等業務。
支撐域
-
CP 域:負責與遊戲研發交互。
營銷域:負責維護高淨值玩家,增加收入。
整體結構
代碼組織架構
-
API:接口實現,無業務邏輯。
Biz-Logic:業務流程編排。
OrderCenter:訂單中心。
PayCenter:支付中心。
Dependency:防腐層。
Datatunnel:數據倉儲。
Constant:常量定義。
CommonTool:通用工具類。
DDD-Framework:基礎服務,如事件總線和命令總線。
Domainshared:領域共享服務。
結語
通過學習和實踐 DDD 概念,對複雜度較高的支付(交易)系統進行了詳細的領域劃分及架構重構,實現了更爲合理的業務邏輯分離和代碼結構優化。
DDD 並不是銀彈,但它幫助我們從業務角度更合理地劃分系統,找到並改進現有架構中的問題。
爲了進一步提升,對 DDD 框架的應用可以參考以下開源項目:
-
https://github.com/bytedance/dddfirework
-
https://github.com/8treenet/freedom
通過不斷學習和優化,我們可以建立更強大的系統架構,從而更好地應對複雜的業務需求和技術挑戰。
參考
-
https://medium.com/@lambrych/domain-driven-design-ddd-strategic-design-explained-55e10b7ecc0f
-
https://delatbabel.medium.com/domain-models-63a33b8d66e6
-
https://medium.com/design-microservices-architecture-with-patterns/microservices-architecture-for-enterprise-large-scaled-application-825436c9a78a
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/pjVv6yIEz03XcYxkdu6R1w