1. 程式人生 > >當DDD遇上微服務

當DDD遇上微服務

?wx_fmt=png&wxfrom=5&wx_lazy=1

標籤 | DDD 微服務 架構

作者 | 張逸

DDD與微服務是可以相通的,其關鍵在於Bounded Context。

分散式系統的定義

在談論這個之前,我們需要就什麼是分散式系統達成一致。在我看來,判斷一個系統是否是分散式的,其標準是看系統中是否存在跨程序通訊。是程序決定了協作與通訊的方式,從而引申出兩種具有本質區別的程式設計模型:

  • 程序內程式設計模型

  • 跨程序程式設計模型

它們之間的區別在於元件之間的呼叫方式。程序內的元件呼叫是非常簡單的,就Java而言,各個駐留於同一個JVM的物件與變數都放在堆記憶體或者棧記憶體中,物件的呼叫(包括方法的呼叫)就是一種記憶體的定址。Java語言通過new關鍵字建立例項,從而獲得該例項的指標,以便於對該例項的屬性與方法進行呼叫。

跨程序元件之間的呼叫方式與程序內呼叫有著本質的。雖然跨程序通訊機制存在各種不同的實現,但它們要考量的因素都是相同的,需要考慮:

  • 程序間的通訊協議

  • 如何定址

  • 訊息的序列化與反序列化

除此之外,在資源管理、事務一致性以及部署方面,都會因為跨程序通訊的原因而產生巨大的差別。

顯然,跨程序通訊固有的複雜度帶來了程式設計模型的改變,但它能夠更加有效地利用硬體資源,卻是分散式系統的主要目標。因此,在IT發展的當前歷史背景下,我們將程序作為邊界來定義分散式系統是非常有意義的。

說明:不同的語言平臺,程序的概念有細微差別,通訊機制自然也有所不同。Java程序等同於作業系統的程序,但Erlang與Go的程序概念則不相同,要更加輕量級。

跨程序元件之間的呼叫方式其實是對通訊機制的一種抽象,它其實又包含了:

  • 程序間通訊機制(如共享記憶體、管道、Socket)

  • 結構化通訊機制(如RPC)

  • 中介軟體通訊機制(分散式物件如CORBA、元件中介軟體如EJB、訊息中介軟體、面向服務與REST)

討論C4模型的Container

Simon Brown提出了自己的C4模型,如下圖所示:

?wx_fmt=jpeg

我們對Container的劃分,可以將程序作為劃分的邊界,即我認為的“物理邊界”。所以Container在架構中除了可以作為邏輯檢視的組成元素之外,也可以視為物理檢視的一部分。

無獨有偶,Alistair Cockburn提出的六邊形架構(又名port-adapter模式)在邊界含義上與Container是與之呼應的。下圖中外部六邊形的邊界就是一個物理邊界,按照之前的分析,我們可以將其視為程序邊界。

?wx_fmt=jpeg

微服務與Bounded Context

微服務作為一個可以獨立部署的微小服務,天生就是一個在物理上隔離的自治服務。從物理檢視的角度看,一個微服務就是C4模型中的Container,也就是六邊形架構中的六邊形。如果我們將六邊形架構與DDD的Bounded Context對應起來,那麼就可以引入DDD的戰略設計來劃分服務邊界,從而幫助我們進行微服務設計了。

一個典型的Bounded Context,可以具有自己的領域模型,訪問專有的資料庫,且可以引入“依賴注入”來滿足Uncle Bob所謂的Clean Architecture思想。下圖所示的Bounded Context的架構,不正是可以表現為一個微服務嗎?

?wx_fmt=png

Context Map對微服務的闡釋

思考DDD中的Bounded Context,可以重點把握以下兩點:

  • Bounded Context與Domain之間的關係

  • Context Map

倘若我們認為Bounded Context與Domain之間存在對應關係,就說明可以從業務架構的層面來設計微服務。通過用例、通用語言或者其他手段,都可以幫助我們識別Bounded Context,進而得到相對合理的服務邊界。

若要判斷微服務的設計是否合理,則可以通過DDD的Context Map進一步驗證和判別Bounded Context的劃分,並理清楚它們之間的關係。

Eric Evans在DDD一書中列出了九種Context Map,基本上可以歸類為:

  • 團隊之間的協作方式

  • 程序之間的整合方式

為什麼說Bounded Context之間的關係可以理解為是團隊之間的協作方式呢?理論根據來自康威定律,即:

設計一個系統(此處泛指更廣泛的系統,而不僅僅是資訊系統)的任何組織都必然會產生一個其結構是該組織通訊結構副本的設計。

一個Bounded Context可能會對映到一個開發團隊,所以討論Bounded Context之間的關係,也可以視為是討論團隊之間的關係。至於程序之間的整合方式,無論是引入ACL(防腐層)還是OHS(開放主機服務),目的都是在實現程序間通訊的同時,更好地做到Bounded Context之間的鬆散耦合。以微服務觀之,就是要滿足服務邊界足夠的自治性。

故而當DDD遇到微服務,其實有許多玄妙的相似之處值得深究。它們之間或許可以碰撞出感情的火花,也未可知呢。

 ?wx_fmt=png

逸言

?wx_fmt=jpeg

一隻奔跑兔子的胡言亂語

長按二維碼關注

特大喜訊!張逸老師即將在成都推出領域驅動設計公開課,兩天的課程,4個單元,從瞭解領域驅動設計、戰略式設計、戰術式設計到領域建模實戰演練,手把手教您進入領域驅動設計殿堂!僅餘最後5席!!!

歡迎點選閱讀原文瞭解詳情

?wx_fmt=jpeg

(以上圖片來自DDD領域建模峰會,版權歸組委會所有)

?wx_fmt=png

識別原文了解DDD公開課詳情