昨天講了暫停開發之後的新方向:接外部訂單的採購系統,以及它需要的東西正躺在安靜的 monolith 裡。今天講怎麼拆。
教科書的微服務拆分有標準劇本,叫 strangler fig(絞殺榕):在 monolith 前面立一個 facade,一次抽一個 bounded context 出去做成新 service,資料靠雙寫、CDC、灰度切流在不停機的前提下搬家,重複到 monolith 被絞殺殆盡——刪掉,慶祝。這套華麗工具箱建立在兩個隱含前提上:**流量不能停,以及 monolith 終須死。**我們的處境,兩個前提剛好都不成立——所以實際做的,是三個完全不同的動作:

**採購:蓋新房。**全新的 service、全新的 DB,不揹舊系統一行程式。新業務的需求形狀(外部訂單、匯入冪等、採購流程)跟商城根本是兩回事,硬塞進 monolith 才是折磨。
**選標:搬家。**拆 monolith 的主要動作就是把選標搬出去、另開自己的 DB。為什麼是它?Day 26 的組織圖已經給了答案:選標從第一天起就是獨立小組(1 後端+1 前端+1 PM),商城和它之間的耦合本來就薄——Conway's law 在拆遷這天從詛咒變成禮物:組織的牆砌在哪裡,系統的自然斷面就在哪裡,拆的時候順著撕就好。
**電商:原地降格。**monolith 沒有被切碎——它整個原地不動,從「系統本身」降格成「三個 service 之一」。沒有客人的商城不值得任何遷移成本,它只要繼續活著服務內部的人。絞殺榕其實不必絞死宿主——Fowler 自己也說過,不再需要改的部分留在原地完全合法;我們只是把這個分支用到了極端:整棵宿主樹都不用改了,新樹在旁邊自己長。
遷移手段,教科書最不推薦的那種:停機,匯出,匯入。那整套讓遷移不中斷的手法,存在理由只有一個:車在行進中,引擎得邊跑邊換;而一個沒有客人的系統,車已經停了,停機成本是零。這是全系列最悲傷的紅利:政治的死亡,給了技術完全的自由。換作全盛期,選標搬家會是一場數月的戰役;在寂靜期,它是一個週末。
拆完的三個 service 怎麼相處?原則一句話:當作完全獨立的系統運作。溝通用 REST——不是事件、不是共享 DB,呼叫就是呼叫,契約就是 API 的形狀。
認證用 JWT,而這裡有個三人團隊風格的決定:**secret key,大家用同一把。**任何 service 都能自己驗 token,不用每次回會員 service 問——零額外基礎設施,對三個人是完美的省。代價也要誠實記帳:一把 secret 洩漏等於全體淪陷、無法對單一 service 撤銷信任。這筆帳在「三個 service 全在同一台 VM、同一群人維護」的現實裡,風險本來就合在一起,分開 secret 買不到多少隔離——知情地冒的險,和無知地冒的險,是兩種工程。
會員 service 的誕生過程,比它的功能更值得寫。它不是架構圖上先畫好的「共用認證中心」——新採購一開始做了自己的會員 service,就是自家的登入和權限;後來選標搬出來,需要認證,就改程式把選標接上同一個 service,它才「升格」成共用的。共用服務的正確誕生時機,不是架構師預言的那天,是第二個客戶出現的那天——在那之前它只是某個系統的登入模組,在那之後它才配叫基礎設施。這是 rule of two 的實戰版:被兩個真實使用者拉出來的抽象,才是真的抽象。
最後是 infra 的收尾,也是這章我最喜歡的一個事實:拆完的三個 service 加會員 service,還是跑在同一台 VM 上——只是變成了不同的 docker compose file。沒有 k8s、沒有 service mesh、沒有多機房。如果你覺得「這樣也算微服務?」,那正是這章想留下的觀點:微服務的邊界是程式碼、資料庫和部署單元的邊界,不是機器的邊界。independent deploy、independent schema、independent failure domain——這些拆的本質利益,兩份 compose file 就全數兌現;把它們散到十台機器上,買的是規模,不是解耦。拆的本質是解耦,不是分散。
這章的重來清單,出奇地短——因為在「三個人、零流量、活下去」的座標系裡,幾乎每個決定我今天都會重做一遍:蓋新房、搬選標、降格 monolith 是三人做得完的唯一拆法;停機遷移在零流量下是最優解;甚至同一把 secret,我大概還是會用,只是會在某個 README 裡寫下「我們知道這代表什麼」。
真正的重來藏在更早的地方:選標搬家之所以是一個週末而不是一場戰役,是因為它跟商城之間的耦合薄;而耦合薄,是組織分工、權限邊界、事實與派生的紀律這些前面章節的決定累積出來的。微服務拆得動不動,在拆之前很久就決定了——這章沒有新的重來,它是前面二十六天所有重來的驗收。
**拆的本質是解耦,不是分散。**一台 VM、兩份 compose file 的「微服務」,比十個 k8s cluster 上的分散式 monolith 更接近微服務的本意。先問「誰跟誰要能獨立演進」,再問「要不要分開跑」——多數團隊把這兩題的順序做反了,買了分散的成本,沒拿到解耦的利益。
**Conway's law 是可以拿來用的,不只是拿來警惕的。**教科書引用它時總是負面的:小心,你的架構會長成你的組織。反過來讀它就是槓桿:想知道系統的自然斷面在哪,看組織的牆在哪。選標小組從成立起就獨立運作,等於一路免費幫未來的拆分畫好了邊界——Day 26 那面「我不熟選標」的知識之牆,在這章變成了最乾淨的服務邊界。
**架構決策的正確性,是情境的函數。**停機遷移、同一把 secret、人工上傳 Excel——教科書會給這三個決定全部亮紅燈;在「三個人、沒有客人、公司在等一個新方向」的座標系裡,它們全是滿分解。工程師的成熟不是背下所有最佳實踐,是知道自己此刻在哪個座標系裡做決定——以及,座標系變了的時候,敢把昨天的紅燈變成今天的綠燈。
拆完的系統安靜地跑著,三個人養得動,新業務有了自己的家。故事的現實線,正在走向終點——但在那之前,明天先岔進一個平行世界:那艘我們當年說好要造、卻從未出航的 SaaS 大船——把它的設計圖畫完。
本文改寫自我的部落格系列《Re:從零開始做直播代購電商平台》,本篇完整版:https://blog.aidan.tw/blog/rezero-microservices/