建置與擴充後端專案:微服務還是單體架構?

建置與擴充後端專案:微服務還是單體架構?

後端的架構,往往決定你一天的工作會有多辛苦。隨著應用程式成長,最初選擇留下的裂痕會慢慢浮現。總有一天你得做出決定。要守住可靠的單體架構,還是把一切都拆成微服務?

沒有銀彈。兩種做法都有它們的位置。正確的選擇,往往更取決於你的團隊結構和事業階段,而不是純粹的技術優劣。這篇文章會談兩個主要選項,再加上一個實際上很常管用的務實中間路線。

1. 兩位選手

微服務架構

微服務的想法很簡單。與其建一個巨大的應用程式,不如建一群小而獨立的服務。每個服務把一件事做好。

把它想成一個去中心化的團隊。每個服務各自管理自己的資料庫,準備好了就能部署,不用問別人准不准。帳務團隊想用 Go,認證團隊喜歡 Rust,兩邊都不用讓步。這種自由讓團隊跑得快。至少理論上是這樣。

在實務上,這很適合大型組織,那種要協調 500 個開發者一起發布一次的場面,對他們來說是惡夢。

圖:微服務架構

Microservices Architecture Diagram

單體架構

單體架構是傳統做法。一個程式碼庫、一個應用程式、一次部署。從使用者介面到商業邏輯再到資料存取,全部住在一起。

「單體」這個詞在某些圈子裡已經快要變成髒話了。但它仍然有實實在在的優點。它簡單。你不需要地圖就能找到函式定義在哪裡。部署就是一支 script。對小型和中型團隊來說,這種簡單就是超能力。它能讓你在不被基礎設施的複雜度拖累的情況下快速前進。

圖:單體架構

Monolithic Architecture Diagram

2. 取捨

為什麼選微服務?

微服務的代價

為什麼留在單體架構?

單體架構的極限

「服務太多」的陷阱

中小型公司常見的反模式,就是最後微服務比工程師還多。我看過 100 個工程師想維護 300 多個服務的組織,結果是一片混亂。

一旦跨越那條線,很多服務就沒有清楚的負責人,或是負責人因為組織重整,接手了他們完全沒有脈絡的服務。你也會花更多時間在更新所有 repo 的相依套件,好清掉漏洞。要把微服務做好,你需要一個專責的平台團隊,以及對工具的大量投資。多數新創根本沒有資源去建那套基礎設施,於是號稱「敏捷」的架構,變成了維護的惡夢。

3. 哪個適合你?

別因為流行就選某種架構。要因為它能解決你當前的問題才選。趨勢不該進到決定裡。

符合以下情況,選微服務:

符合以下情況,選單體架構:

4. 務實之路:模組化單體與逐步拆分

這裡有個祕密。你不必直接跳到微服務。很可能也不該跳。

模組化單體是很棒的折衷。你建一個可部署的單元,但內部在模組之間設下嚴格的界線。Module A 的程式碼不能直接 import Module B 的程式碼,必須透過定義好的公開介面。這樣你得到微服務的程式碼組織好處,卻沒有基礎設施的開銷。

隨著應用程式成長,你可以把需要獨立的部份剝下來。

如何演進:

  1. 找到接縫: 找出應用程式裡像獨立產品一樣運作的部份。「使用者認證」或「圖片處理」都是常見的候選。
  2. 抽出,不要重寫: 把那段程式碼移進另一個服務。它還是可以共用常見的函式庫,例如你的 logging 或 metrics 設定,好維持一致性。
  3. 逐步迭代: 不要一次全拆。也許你只需要一個主要的單體,外加兩個為特定任務準備的小型微服務。
  4. 小心共用程式碼: 在服務之間共用資料庫表格是陷阱。服務一旦拆分,原則上就該擁有自己的資料。

圖:混合做法

Hybrid Architecture Diagram

結論

微服務對單體架構的辯論,常常抓錯重點。重點不是哪種架構在理論上比較優越,而是你現在能忍受哪一組取捨。

從結構良好的單體開始。等痛感出現再拆,別提早動手。未來的你,還有你的 DevOps 團隊,都會感謝你。

© Melvin Laplanche - All rights reserved.