單體優先的微服務架構

作者:Martin Fowler

譯者:林寧

當聽說有團隊在使用微服務架構時候,我注意到了一些規律:

  1. 幾乎所有成功應用微服務的系統,都來自於一個過大單體項目拆分而來。

  2. 幾乎所有我聽到過一開始就選擇使用微服務架構的系統,並從 0 構建,最終的結果都有一系列嚴重的麻煩。

這些規律在我同事中產生了長期的討論:你不應該在新項目之初就採用微服務架構,即使你堅信該應用未來會因業務演進而變得巨大無比。

微服務是一種有用的架構,但是即使是這種架構的擁躉也不得不承認,使用這種架構需要付出額外的成本,這意味者只有更復雜的系統值得使用這種架構。這種代價的本質是管理這些服務所帶來的基本開銷。所以這就是單體優先架構策略的依據, 架構師應在構建新系統時先採用單體架構做設計,即便在項目後期使用微服務架構更有價值。

第一個原因是經典的 Yagni 原則 (譯者注:"You Aren't Gonna Need It" 的縮寫,意在避免過度設計)。當你開始一個新的應用程序時,你如何確定這個應用的特性是用戶有價值的?一個成功的軟件可能背後的設計很糟糕,很難拓展,但是總比一個設計卓越但是沒有價值的系統好。正如我們現在所認識到的,通常判斷一個軟件和想法是否有用的最好方法,是構建一個簡單的版本,看看它的跑起來效果如何。在第一個階段,你需要優先考慮速度 (以及反饋的週期時間),因此微服務的成本是一個累贅,應該被避免。

從微服務開始的第二個問題是,它們只有在服務之間建立良好、穩定的邊界時才能正常工作——這本質上是釐清正確的限界上下文的任務。因爲任何服務之間的功能重構都比在一個龐然大物的單體中要困難得多。不幸的是,即使是在熟悉的領域工作的經驗豐富的架構師,也很難在一開始就確定邊界。通過先構建一個單體應用,你可以在微服務設計刷上一層糖漿之前 (譯者注:比喻微服務的一些額外設施),找出正確的邊界是什麼。它還爲你提供了緩衝時間來開發細粒度服務所需的基礎設施

據我所知,踐行單一優先策略有不同的方式。比如,仔細的從邏輯上設計爲一個類似單體系統的整體,注意內部的模塊化設計,包括 API 邊界和數據的存儲方式。做好這一點,再來開發微服務的系統。然而,如果我聽過很多這樣的成功案例,我會覺得這種方法更合適,實際很難做到。

一種更常見的方法是從一個龐然大物開始,然後逐漸從邊緣剝離微服務。這種方法可能會在微服務體系結構的核心留下一塊巨大的龐然大物,但是大多數新開發都是在微服務中進行的,只是這一塊龐然大物是相對不變的。

另一種常見的方法是先開發一個單體系統,再用一套新的微服務系統完全替換單體結構。很少會有人認同這種辦法,然而建造作爲獻祭架構的單體系統是有好處的(譯者注:一種設計方法,先做簡單的原型系統,再用新的系統代替,其實就是重寫)。不要害怕建造一個你會丟棄的龐然大物,特別是如果一個龐然大物可以讓你很快地進入市場。

還有,我遇到的其他方法是從幾個粗粒度的服務開始,這些服務要比你預期的要大。使用這些粗粒度的服務來習慣處理多個服務,同時享受這樣一個事實:粗粒度減少了你必須不得已進行服務間重構的數量。然後,隨着邊界穩定下來,就會分解爲更細粒度的服務。

雖然我接觸的大多數人傾向於 “單體優先” 的策略,但這不是絕對的。相反的觀點認爲,從微服務開始構建新的系統,可以讓你適應在微服務環境中開發的節奏。要以足夠模塊化的方式構建單體系統,以便將其輕鬆分解爲微服務,需要花費很多甚至太多的編程規則。從微服務開始,你可以讓每個人從一開始就習慣在獨立的小團隊中進行開發,並且在需要的時候,通過服務邊界將團隊分開可以更容易地擴大開發工作。對於那些更有可能儘早獲得足夠穩定邊界的系統來說,這尤其可行。儘管證據不多,但我覺得你不應該從微服務開始,除非你有在團隊中構建微服務系統的大量經驗。

我覺得我還沒有足夠的例子來明確如何決定是否使用 “單體優先” 策略。畢竟,這是微服務的早期階段(譯者注:這篇文章發佈在 2015),可供學習的業界案例相對較少。因此,任何人在這些問題上的建議都需要保持開放性,無論觀點的提出者如何信誓旦旦。

文章來源

Martin Fowler: MonolithFirst (https://martinfowler.com/bliki/MonolithFirst.html)


本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/pwAccA0vhGU3MrWlS3SEEQ