跳至主要內容
ESC
pca-architect-journey — 第 5/13 篇

PCA 架構之旅 05 — Microservices 拆分

PCA

很多團隊一上雲就想「微服務化」,結果拆出 20 個服務、每個都要跟另外 19 個講話,變成分散式的單體(distributed monolith)——比原本的 monolith 還難維護。

PCA 考試會考你「什麼時候該拆、邊界怎麼畫、服務之間怎麼溝通」。這一步就是把 SLO 跟 user story 變成實際的服務邊界。

這是 PCA 架構之旅 的第五步。上一篇 04 · SLO / SLI


為什麼這一步重要

在 PCA case study 題目中怎麼出現

PCA case study 常描述「團隊要獨立部署」「某個模組的流量是其他的 10 倍」「A 功能要每週發版,B 功能半年才動」。這些其實都在暗示服務邊界。題目會要你照這些描述選出合理的拆法,而不是一律丟 GKE。

考生常見錯誤

  • 按技術層拆:資料層一個服務、邏輯層一個服務——這是三層式架構,不是微服務。
  • 按資料表拆:每張表一個服務,結果一筆訂單要 call 10 個服務。
  • 所有服務都同步呼叫:高度耦合、延遲疊加、一個掛全部掛。

核心概念

拆分的三個原則

原則說明
按業務能力(Business Capability)一個服務對應一個業務動作,例如「下單」「查詢庫存」
按變更速率(Rate of Change)常改的跟少改的分開,獨立部署
按擴展特性(Scaling Profile)讀多寫少、計算密集、I/O 密集的分開

DDD(Domain-Driven Design)基本詞彙

  • Bounded Context:一個領域的邊界,例如「訂單」「庫存」「會員」各自是一個 context。
  • Aggregate:一個 context 內資料一致性的單位,例如「訂單」是一個 aggregate,底下有品項、金額、狀態。
  • Context Map:各個 bounded context 之間的關係圖。

服務間溝通模式

模式適用情境GCP 對應
同步 REST/gRPC即時、強依賴Cloud Run + Internal LB、GKE
非同步事件(Pub/Sub)解耦、容忍延遲Pub/Sub
工作佇列重試、限流Cloud Tasks
批次資料管線大量、非即時Dataflow、BigQuery

思考框架

拆分每個服務前先問:

  1. 這個服務獨立部署時,能給使用者什麼完整價值? 不能就還沒拆對。
  2. 它擁有的資料是什麼?誰能寫? 一份資料只能有一個 owner 服務。
  3. 它的 SLO 跟鄰居一樣嗎? 不一樣就該拆。
  4. 它的 scaling 曲線跟鄰居一樣嗎? 不一樣就該拆。
  5. 它被呼叫的路徑是同步還是非同步? 同步太深會疊 latency,應考慮事件化。

走一遍範例 — 登雲書店

根據前面的 persona、story、SLO,登雲書店切出 8 個核心服務(bounded context):

服務清單

#服務名職責變更速率SLO 重點
1catalog-service商品目錄、搜尋中(每週)讀多寫少、99.9%
2inventory-service庫存數量、預留低(每月)強一致、99.99%
3pricing-service定價、促銷高(每日)讀多寫少、99.9%
4cart-service購物車高 QPS、99.9%
5order-service訂單生命週期99.99%、Saga 協調
6payment-service金流整合PCI 隔離、99.99%
7ebook-service電子書閱讀進度寫多讀多、99.9%
8partner-ingest-service書商批次匯入吞吐導向、99%

邊界拆分的理由

  • catalog 跟 inventory 分開:catalog 被大量快取、流量高;inventory 要強一致避免超賣,兩邊的 scaling 特性差很多。
  • pricing 獨立:促銷規則常改,又常跟行銷合作要快速上線,所以跟訂單、庫存解耦。
  • payment 獨立並放在獨立 project:PCI DSS 要求最小作用域(minimized scope),獨立出來就能只讓這個 project 碰卡號。
  • partner-ingest 獨立:批次型,資源用量跟線上服務完全不同,放一起會互相影響。

服務間溝通設計

  • 同步呼叫:cart → pricing、cart → inventory(結帳前查詢)。
  • 非同步事件:order → payment → order(使用 Pub/Sub 通知結果,避免 order 等 bank API 20 秒)。
  • 事件廣播:inventory 變動發 inventory.updated event,catalog 與搜尋索引各自訂閱。
  • 批次管線:partner-ingest 用 Dataflow 寫入 inventory 與 pricing 的專屬 import table,再交換進入正式表。

共同治理

  • 每個服務一個 GCP project 或至少一個 namespace,用 Workload Identity 管 IAM。
  • 服務間呼叫走 Internal HTTP(S) LB 或 gRPC;對外只開 API Gateway。
  • 共用 schema 放在 single repo 的 schemas/ 目錄,用 Protobuf + Buf 做版本管理。

常見陷阱

  • 拆太細變奈米服務:8 個服務剛好,30 個就是災難。先從 3–5 個開始,跑一陣子看狀況再拆。
  • 共用資料庫:兩個服務共用同一張表等於沒拆。每個服務要有自己的儲存。
  • 同步呼叫鏈超過 3 跳:A → B → C → D 的同步鏈,一個慢全部慢。超過 3 跳就要考慮事件化。
  • 忽略組織結構:Conway’s Law 說系統架構會長得像組織架構。6 人團隊硬切 8 個服務會沒人顧得了。

延伸閱讀


下一步:服務邊界有了,接著就要設計它們對外的契約,也就是 REST API 設計

🎯 換你練習

理論讀完,換自己來。到 架構師設計工作坊 · 步驟 5 填入你的 case study,邊寫邊內化。

pca-architect-journey — 5/13 完成 查看系列全覽 →

留言討論

徽章解鎖!