單體優先還是直接採用微服務?這個問題隨著馬丁大叔的文章Monolith First1釋出,顯得再次熱鬧起來。
在我看來,從三個方面嘗試分析這個問題。
- 微服務架構和單體架構區別是什麼?
- 系統建立之初這些區別意味著什麼?
- 如果系統建立之初使用單體架構,後續過渡到微服務架構代價如何?
微服務架構和單體架構區別是什麼?
微服務架構與單體架構的區別,本質是系統各部件間分隔的強度大小。
從下面幾個方面看一看:
微服務 | 單體 | |
---|---|---|
領域分隔 | 領域被分隔為微服務。分隔力度大,相互間的影響較小。微服務可以各自擁有不同的進化節奏,不同領域的創新可以分別實施、快速落地。 領域間的呼叫相對困難,需要一些基礎服務幫助,比如服務註冊和定址等。 |
領域的分隔表現為模組的分隔,其間的聯絡簡單直接。 |
團隊分隔 | 團隊按微服務配置。成員專注於小的領域和程式碼集。溝通成本低。容易學習。 需要部件之間緊密協作時相對困難,比如當程式碼需要在部件之間移動。 |
整個系統一個團隊。如果系統變得龐大,成員就需要學習大量的程式碼和領域知識,團隊內的溝通和協作也變得低效。不得不分割團隊時容易按職責分割,形成豎井團隊2。 |
技術分隔 | 在不同的微服務中,可以根據不同的業務特性分別選擇適當的技術。包括可以分別選擇適當的儲存策略。 | 整個系統(甚至整個企業)統一的技術棧,管理起來看似簡單。但有時候統一的標準並不適合所有的實際情況。 |
執行時分隔 | 各部件通常執行於不同的程式。容易進行錯誤隔離。可以分別伸縮。 執行時需要管理的單位較多,相對困難,需要一些專門的運營工具。 |
通常執行於同一個程式。部件間協作的額外開銷很小。 |
系統建立之初這些區別意味著什麼?
通過上面的羅列比較我們可以看到:對於複雜系統,微服務架構可以有效地分隔複雜度。
但微服務架構有風險:首先需要前期就對領域有良好的認識以便分割。其次需要一定的基礎服務和工具。如果團隊並不熟悉這種相對較新的架構,學習和適應的成本還是比較高的。
如果我們的系統在建立之初比較簡單,在各個方面基本上並不需要高強度的分隔,單體架構往往就能夠滿足要求。
我們看看什麼情況下可能有可能直接從微服務架構開始:
- 我們的系統所面對的領域規模很大,需要進行分割;同時,我們很清楚如何分隔。(……,好吧,這種情況基本沒有,囧)
- 我們的團隊規模太小,從一開始就無法單獨承擔系統的規模。
- 我的企業預設架構就是微服務,很多系統已經實踐過了。
- 我的老闆認為微服務很酷,必須上。
- ……
這些情況下,如果各方充分認識到微服務的代價並作出應對預案,是可以直接應用微服務架構的。
在所有的代價中,有一種最重要,值得再說一遍:領域劃分不清晰的情況下請務必慎重,在微服務間移動領域邏輯是非常昂貴的。
已有單體架構系統過渡到微服務架構代價如何?
馬丁大叔提出的“扼死大法”3是一種自然有效的過渡方式。但跟其他所有的方式一樣。
這個辦法的難度和相關代價還是取決於單體本身的結構特點。
如果單體自身擁有良好的結構,容易從中剝離出相對獨立的領域邏輯。那我們可以有條不紊逐步剝離:
- 為新特性建立微服務,單體保持不變。
- 在單體中識別內聚的子領域,對應地各自剝離為微服務。
- 按照業務價值和變化頻度安排優先順序。
- 並不追求完全消滅單體。
另一種情況,單體本身是一個大泥球。那就沒有那麼幸運了,我們必須先整理單體本身。
結論
- 單體優先,同時請做好準備,你可能很快需要過渡到微服務。所以做一個“微服務友好”的單體,並適時開始基礎服務和團隊技能的準備。
- 讀到這裡仍然覺得自己應該立即微服務的同學:請不猶豫地微服務吧。
- Monolith First↩
- “豎井團隊”被認為在大部分情況下是反模式。參見“反Conway策略”↩
- StranglerApplication↩