微服務模式:業務服務模式
無論是單體應用還是微服務,構建企業應用的業務邏輯/服務在更多方面上都有相似之處而不是差異。在兩種方法中,都包含服務、實體、倉庫等類。然而,也會發現一些明顯的區別。在本文中,我將試圖以概念性的方式強調這些區別,通過重新審視每種架構中內置的一些核心設計模式和原則。
那么,讓我們從“六邊形架構”(Hexagonal Architecture)開始,以及它與企業應用業務邏輯的關系。
六邊形架構
任何企業應用中的業務服務理論上都在其核心使用了六邊形架構
圖01 — 六邊形架構
六邊形架構/端口和適配器架構是一種用于軟件架構設計的架構模式。它旨在創建松散耦合的應用組件,可以通過端口和適配器與其軟件環境輕松連接。(維基百科)
如圖01所示,“業務服務邏輯”是六邊形架構的核心。
領域模型模式
傳統的過程式事務腳本模式通常是實現“簡單業務邏輯”的一種很好的方式。
- 事務腳本模式:將業務邏輯組織成一組每個類型請求一個的過程性事務腳本。 但是,當實現“復雜業務邏輯”時,應考慮使用領域模型模式*,*基本上是使用面向對象設計(OOD)。
- 領域模型模式:將業務邏輯組織成一個對象模型,其中包含具有狀態和行為的類[1]。
領域驅動設計(DDD)
然而,領域模型模式在典型的單體應用后端上效果良好,但在微服務應用中有一定局限性,這基本上由領域驅動設計(DDD)所覆蓋。
DDD是對OOD的細化,它是一種開發復雜后端業務邏輯的方法。 使用DDD時,每個服務都有其自己的領域模型,避免了整個應用程序的統一領域模型的問題。
戰略模式與戰術模式
DDD提出了多種戰略模式和戰術模式。
其中兩個關鍵的戰略模式是子域(Subdomains)和有界上下文(Bounded Contexts)。這些模式通常有助于在應用程序中分解業務邏輯。
根據Vaughn Vernon的《實現領域驅動設計》一書[5],子域存在于問題空間,有界上下文存在于解決方案空間。 換句話說,有界上下文幫助您管理應用程序中的復雜性,而子域則有助于組織和管理業務域的不同方面。 在實踐中,有界上下文通常與一個子域對齊,但也可能在單個子域內有多個有界上下文,或者有一個跨越多個子域的有界上下文。 在每個有界上下文中,我們可以建立專門負責各自領域的團隊來進行管理。這些團隊負責構建給定領域的構件、需求、規范和服務。 戰術模式基本上是您在服務中定義的領域模型的構建塊。其中一些戰術設計模式是實體(Entity)、值對象(Value Object)、工廠(Factory)、倉庫(Repository)、服務(Service)和聚合(Aggregate)。 在本文中,我們將更深入地研究聚合模式及其在典型微服務設計中的用途。
聚合模式
聚合模式:將一個領域模型組織為一組聚合,每個聚合都是一個可以視為單元的對象圖[1] 傳統的領域模型是一個類和它們之間的關系的集合。在這個模型中,所有類和關系都是相互關聯的,相對較難找到每個業務對象的邊界,這是復雜微服務設計的關鍵要求。DDD中的聚合模式可以幫助您解決這個問題。 在聚合模式中,根據定義,將領域模型結構化為一組聚合使其邊界顯式并更易于理解。
每個聚合都有一個根實體(聚合根),可能有一個或多個值對象。
但這并不意味著一個聚合只能有一個實體。您可以在一個聚合中有多個實
體。但最佳實踐是在一個聚合內有最少數量的實體,以提高每個事務的可擴展性。
聚合根是主要實體,它保存對領域模型中其他聚合的引用,并且是唯一一個可以用于直接查找的聚合中的實體。在聚合中的組件(例如值對象)將彼此間有對象引用。在圖02中,您將看到這一點,每個引用的聚合主鍵ID都存儲在主要聚合中,即聚合01。這允許在領域模型內部實現更松散耦合的架構。
聚合通常是從數據庫完整加載(以避免任何延遲加載)。即使在它被刪除的同時,聚合也會將其邊界內的所有對象從數據庫中移除。除此之外,將它們存儲在像MongoDB這樣的NoSQL數據庫中更加簡單。
簡而言之,應用DDD聚合模式將:
- 將服務中的領域模型模塊化。
- 消除服務之間的對象引用(在DDD中,不同聚合中的類之間的引用是基于主鍵值而不是對象引用)。
- 事務只能創建或更新單個聚合。這允許應用程序使用Saga模式更新多個聚合。
聚合與Saga模式
Saga編排了一系列(微)服務中的本地事務,以保持數據一致性。每個本地事務都與一個映射的聚合相關聯(參見圖03)。
圖03 — 連接聚合模式和Saga模式
聚合與有界上下文
在技術理論上,有關“有界上下文”和“聚合”之間的區別有一些誤解。因此,了解它們之間的區別及其與微服務的關聯至關重要。
如前所述,微服務可以通過“有界上下文”或“領域”來解釋。每個“有界上下文”將有一個或多個“聚合”。
圖04 — 有界上下文與聚合
因此,在實踐中,微服務不應小于一個聚合,也不應大于一個有界上下文。
領域事件模式
在概念上,當聚合被創建和更新時,它們會發布領域事件。聚合知道其狀態何時發生變化,因此知道要發布的事件。
這些領域事件最終作為消息發布到消息代理(例如Kafka)。
領域事件模式:當聚合被創建并且經歷某些其他重要變化時,發布領域事件。
事件風暴
有幾種策略可以識別領域事件。其中一種流行的策略是事件風暴,可以通過一種研討會形式的安排來執行,以了解具有許多事件的復雜領域。這種研討會的最終結果是一個以事件為中心的領域模型,其中包含聚合和事件。