微服務:限界上下文(Bounded Context)

YC
程式愛好者
Published in
Apr 12, 2022

在微服務領域當中,經常會使用限界上下文這概念來界定不同服務的業務範圍。
「限界上下文」在文字上可能是相當難理解,但這一個用語其實是出自 DDD ( Domain Driven Development ) 的術語。

為什麼我們需要範圍界定?

微服務作為一種軟體架構,我們需要記住是為了設計出一種更易修改且可以快速部置的軟體,從而減低由於改變與部置所造成的風險。將原來的業務們劃分出來,從而變成一個個低耦合高內聚 (Lossely Coupled, Highly Cohesive) 的組件。

而範圍界定就是我們對於該如何劃分的業務的手段!在常見的微服務架構中,會使用 DDD 來作為中的 bounded context 概念來幫助架構師劃分出「適合大小」的服務。

Domain Driven Development

DDD 是一組巨大的開發概念,在這篇中我們將不會詳細了解整個 DDD 的概念,但我們可以了解 DDD 在微服務中提供了什麼方法來讓我們更好的設計程式。

重點在於領域 ( Domain ),DDD 希望透過現實中的領域去對軟體進行設計。在這個領域中會有相應領域的專家、軟體專家及為其發展而出的語言 ( Ubiquitous Language ) 去作為開發時的描述語,並為模型建模。
但我們暫時只會使用 DDD 中的限界上下文這概念來劃分服務的範圍。

限界上下文 Bounded Context

限界上下文可以說是一個集合,內含該領域中所需的業務內容,並為其設立邊界,確保語言的一致性。

每一個 BC 都有著多個內部模型,這些內部模型是對 BC 的概念支持 (supporting concepts)。如在訂單的 BC 中,內部模型可能是訂單狀態、付款、物流狀態等。

如同現實的業務內容,一個給定的領域都包含多個 BC,每個限界上下文中的模型分成兩部分,一部分需要與外部通信,另一部分不需要。就微服務而言,訂單中的物流狀態可能是需要從物流的 BC 中得來,這就是一個 BC 對另一個 BC 獲得信息、或者向其發起請求。

但是,當你思考組織內的 BC 時,不應從共享數據的角度來考慮,而應該從這些上下文能夠提供的功能來考慮。我們不應該因為訂單中有物流狀態的資訊,就把兩者放在同一個 BC 中。
對一個店家來說,訂單和物流明顯是兩個獨立的 BC,它們都有明確的對外接口,也都有著只需要自己知道的細節。但訂單不需要完全了解物流的內部細節,比如訂單中不用知道物流司機的名字。

到現在為止,微服務聽起來也很像限界上下文,而微服務正應與限界上下文保持一致。那限界上下文是否就等於微服務呢?實則不然,微服務應照限界上下文來劃分,但也可能出現一個限界上下文由多個服務組成,以提供不同功能的服務給限界上下文。

劃分上下文

當考慮微服務的邊界時,先考慮從粗粒度較大的上下文開始,再從中劃分出更小粗粒度的上下文。有時候我們會常見到一個粗粒度較大的限界上下文內嵌著好幾個小粗粒度的上下文,而這些內嵌的上下文會被建成服務,如下:

這樣外部仍認為他們在使用物流功能,但實際上請求被分別轉送到多個服務上。

另外,也有一種策略是移除高層次的上下文,直接將所有內嵌的上下文提升為最高層次的上下文,如下:

我們很難說哪一種方式更為合理,但我們可以按組織結構來決定,如果服務都是由不同團隊維運,那完全分離的方法可能會更好地分配工作。相反,如果務務由一個團隊管理,那內嵌式就更顯合理了。

當在設計微服務時,限界上下文是達到低耦合高內聚的重要方法,通過了解領域的內容與邊界,透過邊界來設計服務的業務範圍,應可保證獲得微服務架構所帶來中的好處。

如果你覺得我的文章幫助到你,希望你也可以為文章拍手,分別 Follow 我的個人頁與程式愛好者,按讚我們的粉絲頁喔,支持我們推出更多更好的內容創作!

--

--

YC
程式愛好者

提供更精確的技術內容為目標,另創立「程式愛好者」專頁。資深軟體工程師,專研後端技術、物件導向、軟體架構。