微服務領域驅動設計 - semaphoreci
微服務是開發軟體的最具可擴充套件性的方式。但是你需要一個好的設計,讓開發團隊自主工作和部署,而不會互相干擾,否則你將失去可擴充套件性的好處。
領域驅動開發允許我們通過將更大的系統分解為獨立的單元、瞭解每個單元的職責並確定它們之間的關係來規劃微服務架構。在本文中,我們將學習領域驅動設計的基礎知識以及如何將其應用於微服務。
什麼是領域驅動設計?
領域驅動設計 (DDD) 是一種軟體設計方法,開發人員在其中構建模型以瞭解領域的業務需求。這些模型作為開發軟體的概念基礎。
根據域驅動設計的作者 Eric Evans 的說法:解決軟體核心的複雜性,領域是:
知識、影響或活動的領域。使用者應用程式的主題領域是軟體的領域。
一個人解決問題的能力取決於一個人對該領域的理解能力。開發人員是聰明人,但他們不可能是所有領域的專家。他們需要與領域專家合作,以確保程式碼符合業務規則和客戶需求。
上圖說明:開發人員和領域專家使用統一的語言來共享知識、文件、計劃和程式碼。
微服務架構的兩個最重要的 DDD 概念是:有界上下文和上下文對映。
限界/有界上下文 (BC)
單詞出現的環境決定了它的含義。根據上下文,“書”可能指的是書面作品,也可能意味著“預訂房間”。有界上下文(BC)是一個術語具有明確和明確含義的空間。
在 DDD 之前,通常的做法是嘗試找到一個跨越整個領域的模型。問題是域越大,就越難找到一致統一的模型。DDD 的解決方案是識別 BC,以便將域分解為可管理的子域。
在軟體中,我們需要精確。這就是定義 BC 至關重要的原因:它為我們提供了一個精確的詞彙表,稱為通用語言,可用於開發人員和領域專家之間的對話。無處不在的語言存在於整個設計過程、專案文件和程式碼中。
上下文對映
BC 的存在預示著對通訊渠道的需求。例如,如果我們在電子商務領域工作,銷售人員應該在銷售產品之前檢查庫存。一旦售出,就需要通過運輸來確保將產品送到正確的地址。在 DDD 中,這些關係以上下文對映的形式描述。
微服務領域驅動設計
DDD 分兩個階段進行:
- 在戰略階段,我們確定 BC 並將它們對映到上下文地圖中。
- 在戰術階段,我們根據子域的業務規則對每個 BC 進行建模。
讓我們看看每個階段如何在微服務架構設計中發揮作用。
1、戰略階段
在此階段,我們邀請開發人員、領域專家、產品所有者和業務分析師進行頭腦風暴、分享知識並制定初步計劃。在主持人的幫助下,這可以採取事件風暴研討會的形式,我們在其中構建模型並從領域中的重大事件開始識別業務需求。
在戰略 DDD 中,我們採用高層次、自上而下的設計方法。我們首先分析域以確定其業務規則。由此,我們得出一個 BC 列表。
邊界充當天然屏障,保護內部模型。因此,每個 BC 都代表了一個實現至少一個微服務的機會。
接下來,我們必須決定 BC 將如何通訊。Eric Evans列出了七種型別的關係,而其他作者列出了其中的六種。不管我們如何計算它們,至少三個(共享核心、客戶/供應商和遵從者)意味著緊密耦合,這是我們在微服務設計中不想要的,可以忽略不計。這給我們留下了四種型別的關係:
- 開放主機服務(OHS):服務提供者定義一個開放協議供其他人使用。這是一種開放式的關係,因為消費者需要遵守協議。
- 已釋出語言(PL):此關係使用眾所周知的語言,例如 XML、JSON、GraphQL 或任何其他適合該領域的語言。這種型別的關係可以與 OHS 結合使用。
- 反腐敗層(ACL):這是服務消費者的防禦機制。反腐敗層是在下游服務之前實現的抽象和翻譯包裝層。當上遊發生變化時,消費者服務只需要更新 ACL。
- 不同的方式:當進一步分析發現兩個服務之間的整合沒有什麼價值時,就會發生這種情況。這與關係相反——這意味著 BC 沒有聯絡,也不需要互動。
在我們的戰略 DDD 分析結束時,我們得到一個詳細描述 BC 及其關係的上下文圖。
戰術階段
在內心深處,軟體開發是一種建模練習;我們將現實生活中的場景描述為模型,然後用程式碼解決它。在上一階段,我們確定了 BC 並繪製了它們的關係。在這個階段,需要開發人員精通 DDD 理論,我們將放大每個上下文以構建詳細的模型。
使用 DDD 建立的模型與技術無關——它們沒有說明底層的堆疊。相反,我們專注於對子域進行建模。我們模型的主要構建塊是:
- 實體:實體是具有隨時間持續存在的身份的物件。實體必須具有唯一識別符號(例如,客戶的帳號)。雖然實體識別符號可以在上下文邊界之間共享,但實體本身不需要在每個 BC 中都相同。每個上下文都可以擁有給定實體的私有版本。
- 值物件:值物件是沒有標識的不可變值。它們代表您模型的原語,例如日期、時間、座標或貨幣。
- 聚合:聚合建立實體和值物件之間的關係。它們代表一組可以被視為一個單元並且始終處於一致狀態的物件。例如,客戶下訂單並擁有書籍,因此可以將實體 customer、order 和 book 視為一個聚合。聚合必須始終由稱為根實體的主實體引用。
- 領域服務:這些是實現業務邏輯或功能的無狀態服務。域服務可以跨越多個實體。
- 領域事件:對於微服務設計至關重要,領域事件會在發生某些事情時通知其他服務。例如,當客戶購買一本書時,付款被拒絕,或者使用者已經登入。微服務可以同時產生和消費來自網路的事件。
- 儲存庫:儲存庫是聚合的持久容器,通常採用資料庫的形式。
- 工廠:工廠負責建立新的聚合。
領域驅動設計是迭代的
雖然看起來我們必須首先編寫一個詳盡的領域描述,然後才能開始處理程式碼,但現實情況是,DDD 與所有軟體設計一樣,是一個迭代過程。
在紙面上,限界上下文和上下文對映可能看起來不錯,但在實施時,它們可能會轉化為太大而無法正確稱為微服務的服務。相反,具有重疊職責的聊天微服務可能需要合併為一個。
隨著開發的進展,您對領域有了更好的理解,您將能夠做出更好的判斷、增強模型並更有效地進行溝通。
更多設計微服務的方法
DDD 無疑是一種重理論的設計模式。因此,僅當正在開發的系統足夠複雜以保證額外的規劃工作時才推薦使用。
其他方法,例如測試驅動開發(TDD) 或行為驅動開發(BDD),對於更小、更簡單的系統可能就足夠了。TDD 在處理單個微服務或什至僅由少數服務組成的應用程式時是最快的開始並且效果最好。
在更大的範圍內,我們可以使用 BDD,它迫使我們通過整合和驗收測試來驗證批發行為。如果您從事低到中等複雜度的設計,BDD 可能會很好地工作,但是一旦您達到某個閾值,維護測試可能會減慢您的速度。
您還可以將這三種模式結合起來,為每個開發階段選擇最好的一種。例如:
- 識別微服務及其與戰略 DDD 的關係。
- 使用戰術 DDD 對每個微服務進行建模。
- 由於每個團隊都是自治的,因此他們可以選擇採用 BDD 或 TDD(或兩者混合)來開發微服務或微服務叢集。
相關文章
- 領域驅動設計,中臺與微服務微服務
- 微服務架構設計基礎之領域驅動設計微服務架構
- 結合領域事件和微服務的實現領域驅動設計 - Alagarsamy事件微服務
- 領域驅動設計戰術模式--領域服務模式
- 微服務與領域驅動設計,架構實踐總結微服務架構
- 領域驅動設計之實戰許可權系統微服務微服務
- DDD領域驅動設計:領域事件事件
- 理解領域驅動設計
- MasaFramework -- 領域驅動設計Framework
- 領域驅動設計示例
- 領域驅動設計戰術模式--領域事件模式事件
- 戲說領域驅動設計(廿五)——領域事件事件
- 領域驅動設計簡介
- 實現領域驅動設計
- 領域驅動設計核心概念
- 當今微服務盛行之架構師必經之路-領域驅動設計-上微服務架構
- 當今微服務盛行之架構師必經之路-領域驅動設計-下微服務架構
- 領域驅動設計與模型驅動設計的關係模型
- 事件驅動的微服務-事件驅動設計事件微服務
- JavaScript中的領域驅動設計JavaScript
- 淺談DDD(領域驅動設計)
- 淺談 DDD 領域驅動設計
- 前端開發-領域驅動設計前端
- 領域驅動設計中的模型模型
- DDD-領域驅動設計示例
- SummerSoC 2020:基於領域驅動的服務設計(SOA/微服務) – Stefan Kapferer微服務
- Java開發架構篇:領域驅動設計架構基於SpringCloud搭建微服務Java架構SpringGCCloud微服務
- 領域驅動設計 (DDD) 簡介 - jannikwempe
- 領域驅動設計(DDD)入門&概要
- 領域驅動設計DDD應用心得
- 領域驅動設計與敏捷開發敏捷
- 最常見領域驅動設計錯誤
- 領域驅動設計整合與架構架構
- 問題驅動設計與領域驅動設計的區別 - abdullin
- 使用領域驅動設計DDD和CQRS實現身份驗證的微服務原始碼專案微服務原始碼
- 在複雜領域中設計軟體:領域驅動設計 - levelup
- 領域驅動設計(DDD)實踐之路(一)
- 領域驅動設計的概念解釋 -DEVdev