🎯 什麼情境該想到我

當你要決定「一個微服務該多大、邊界畫在哪、從單體怎麼拆」時。

⚙️ 怎麼用

  1. 按業務能力/限界上下文切(見 工具-限界上下文),不按技術分層切。
  2. 檢驗好邊界:服務能獨立變更、獨立部署嗎?若一個改動總要同時改好幾個服務 → 邊界錯了。
  3. 每個服務擁有自己的資料:不共用資料庫,透過 API/事件互動(避免隱性耦合)。
  4. 服務間別太聊天:若兩服務呼叫極頻繁,可能該合併——高內聚該在同一服務內。
  5. 演進式拆分:從單體開始,沿著真實痛點與清楚的接縫逐步剝離(見 工具-架構隨業務規模演進)。

📌 這一組三張卡:工具-服務架構的演進與拆分=「有哪些選項」|工具-架構隨業務規模演進=「什麼時候動」|本卡=「切在哪、怎麼切」

★ 檢驗邊界對不對的五個問題

① ★ 能獨立部署嗎?
   —— 每次發布都要和別的服務按順序一起上 → ★ 分散式單體,邊界錯了

② ★ 一個典型的功能改動,會動到幾個服務?
   —— 常常要改 3 個以上 → 邊界橫切了業務能力

③ ★ 服務之間的呼叫頻率高嗎?
   —— 一個請求要來回呼叫 5 次 → ★ 高內聚的東西被切開了,該合併

④ ★ 需要跨服務的交易嗎?
   —— 需要 → 聚合被切開了(見 [[工具-分散式事務的取捨]])

⑤ ★ 資料是各自擁有的嗎?
   —— 共用同一張表 → 沒有真的拆開,只是兩個程式連同一個 DB

★ 第 ① 題是最實用的單一判準:「能不能只部署這一個?」

★ 絞殺者模式(Strangler Fig):怎麼安全地剝離

① 在單體前面放一層「門面」(proxy / API gateway / 路由層)
     Client ──▶ [Facade] ──▶ 單體

② 建新服務,門面把「一小部分流量」導過去(先唯讀、先內部使用者)
     Client ──▶ [Facade] ─┬─▶ 單體
                          └─▶ 新服務   ← ★ 可隨時切回

③ ★ 雙寫 + 對帳:兩邊都寫,比對結果,確認新服務行為一致

④ 逐步提高流量比例,觀察指標

⑤ 舊路徑流量歸零後,★ 觀察一段時間再刪除

★ 關鍵是「每一步都可以立刻回退」。
大爆炸式重寫(big bang rewrite)失敗率極高,因為你在一個無法驗證的狀態下走了幾個月。

★ 最難的部分:拆資料

❌ 兩個服務共用同一個資料庫 → ★ 這不是微服務,是「兩個程式共用一個全域變數」
   任一方改 schema 都會弄壞對方,而且沒有編譯器會警告你

拆資料的步驟:

① 先拆「程式碼層」:所有存取都走一個 repository 介面(見 [[工具-接縫]])
② 拆「schema 層」:不同的表分開、拿掉跨表的外鍵與 JOIN
③ ★ 拆「實體層」:真正搬到不同的資料庫
④ 需要對方的資料時 → API 呼叫、事件複製、或 CQRS 讀模型

★ 步驟 ② 通常最痛:JOIN 不見了,要在應用層組合資料。
這也是為什麼「需要頻繁 JOIN 的資料不該被切開」——它是高內聚的訊號。

★ 切錯的三種典型形態

錯誤切法症狀正解
★ 按技術分層切api-service / logic-service / data-service
→ 每個功能都要改三個
按業務能力切
★ 切得太細(奈米服務)20 個服務,每個 200 行;一個請求跨 8 個服務合併。服務的大小該由「團隊能負責的範圍」決定
★ 切在聚合中間需要分散式事務才能維持不變式聚合不可切開(見 工具-實體值物件與聚合)

★ 服務之間該怎麼通訊

方式何時
同步 HTTP/gRPC★ 需要立即的回應、且呼叫鏈短
★ 非同步事件預設優先考慮:解耦、可重放、天然支援最終一致
共用資料庫❌ 不要
檔案/批次大量資料的定期同步

★ 同步呼叫會傳遞失敗:A → B → C,C 掛了 A 也掛。
每一層同步呼叫都在降低整體可用性(可用性相乘)。
→ 能非同步就非同步(見 工具-訊息傳遞整合模式)。

★ 拆之前先問:能不能不拆

合併回單體也是一個正當的架構決定。
如果兩個服務總是一起改、一起部署、互相頻繁呼叫——它們本來就是一個東西。
★ 「拆了之後發現不對就合併回去」不是失敗,是正確的演進。

🧪 我實際套用的紀錄

  • 2026-07-15:(待填)

⚠️ 注意 / 什麼時候不適用

  • ★★ 不要大爆炸重寫。用絞殺者模式,每一步可回退。
  • ★ 共用資料庫 = 沒有拆開。這是最常見的假微服務。
  • ★ 拆分期間會同時維護兩套,成本更高。要有明確的完成期限與「刪除舊路徑」的任務,
    否則會永遠停在中間狀態——那是最糟的狀態。
  • 雙寫期間的一致性:兩邊寫入可能不一致 → 一定要有對帳(見 工具-分散式事務的取捨)。
  • ★ 邊界會改變。業務變了,昨天對的邊界今天就錯了。保持能再切一次的能力,
    而不是追求「一次切對」。
  • 拆分的收益要能說清楚。「為了微服務」不是收益;「讓 A 團隊不用等 B 團隊部署」才是。
  • 先在單體內劃清邊界(模組化單體)再拆——這樣切錯的成本只是改資料夾。

🔗 相關工具