單體優先還是微服務?

聶同學發表於2016-04-11

單體優先還是直接採用微服務?這個問題隨著馬丁大叔的文章Monolith First1釋出,顯得再次熱鬧起來。

在我看來,從三個方面嘗試分析這個問題。

  1. 微服務架構和單體架構區別是什麼?
  2. 系統建立之初這些區別意味著什麼?
  3. 如果系統建立之初使用單體架構,後續過渡到微服務架構代價如何?

微服務架構和單體架構區別是什麼?

微服務架構與單體架構的區別,本質是系統各部件間分隔的強度大小。

從下面幾個方面看一看:

微服務 單體
領域分隔 領域被分隔為微服務。分隔力度大,相互間的影響較小。微服務可以各自擁有不同的進化節奏,不同領域的創新可以分別實施、快速落地。
領域間的呼叫相對困難,需要一些基礎服務幫助,比如服務註冊和定址等。
領域的分隔表現為模組的分隔,其間的聯絡簡單直接。
團隊分隔 團隊按微服務配置。成員專注於小的領域和程式碼集。溝通成本低。容易學習。
需要部件之間緊密協作時相對困難,比如當程式碼需要在部件之間移動。
整個系統一個團隊。如果系統變得龐大,成員就需要學習大量的程式碼和領域知識,團隊內的溝通和協作也變得低效。不得不分割團隊時容易按職責分割,形成豎井團隊2
技術分隔 在不同的微服務中,可以根據不同的業務特性分別選擇適當的技術。包括可以分別選擇適當的儲存策略。 整個系統(甚至整個企業)統一的技術棧,管理起來看似簡單。但有時候統一的標準並不適合所有的實際情況。
執行時分隔 各部件通常執行於不同的程式。容易進行錯誤隔離。可以分別伸縮。
執行時需要管理的單位較多,相對困難,需要一些專門的運營工具。
通常執行於同一個程式。部件間協作的額外開銷很小。

系統建立之初這些區別意味著什麼?

通過上面的羅列比較我們可以看到:對於複雜系統,微服務架構可以有效地分隔複雜度。

但微服務架構有風險:首先需要前期就對領域有良好的認識以便分割。其次需要一定的基礎服務和工具。如果團隊並不熟悉這種相對較新的架構,學習和適應的成本還是比較高的。

如果我們的系統在建立之初比較簡單,在各個方面基本上並不需要高強度的分隔,單體架構往往就能夠滿足要求。

我們看看什麼情況下可能有可能直接從微服務架構開始:

  • 我們的系統所面對的領域規模很大,需要進行分割;同時,我們很清楚如何分隔。(……,好吧,這種情況基本沒有,囧)
  • 我們的團隊規模太小,從一開始就無法單獨承擔系統的規模。
  • 我的企業預設架構就是微服務,很多系統已經實踐過了。
  • 我的老闆認為微服務很酷,必須上。
  • ……

這些情況下,如果各方充分認識到微服務的代價並作出應對預案,是可以直接應用微服務架構的。

在所有的代價中,有一種最重要,值得再說一遍:領域劃分不清晰的情況下請務必慎重,在微服務間移動領域邏輯是非常昂貴的。

已有單體架構系統過渡到微服務架構代價如何?

馬丁大叔提出的“扼死大法”3是一種自然有效的過渡方式。但跟其他所有的方式一樣。

這個辦法的難度和相關代價還是取決於單體本身的結構特點。

如果單體自身擁有良好的結構,容易從中剝離出相對獨立的領域邏輯。那我們可以有條不紊逐步剝離:

  1. 為新特性建立微服務,單體保持不變。
  2. 在單體中識別內聚的子領域,對應地各自剝離為微服務。
  3. 按照業務價值和變化頻度安排優先順序。
  4. 並不追求完全消滅單體。

另一種情況,單體本身是一個大泥球。那就沒有那麼幸運了,我們必須先整理單體本身。

結論

  • 單體優先,同時請做好準備,你可能很快需要過渡到微服務。所以做一個“微服務友好”的單體,並適時開始基礎服務和團隊技能的準備。
  • 讀到這裡仍然覺得自己應該立即微服務的同學:請不猶豫地微服務吧。

  1. Monolith First
  2. “豎井團隊”被認為在大部分情況下是反模式。參見“反Conway策略”
  3. StranglerApplication

相關文章