微服務設計
Sam Newman|該不該拆、拆的代價
🧭 邊界對齊業務領域 高內聚低耦合
🎯 什麼情境該想到我
當系統/模型越長越大越糊,或發現「同一個名詞在不同部門意義不同」時。
⚙️ 怎麼用
- 劃出邊界:在某個邊界內,一套模型與 工具-通用語言 保持一致、無歧義。
- 一個詞在不同上下文意義不同 → 就該分成不同上下文(例:「商品」在銷售 vs 物流意義不同)。
- 用 Context Map 描述上下文之間的關係(上下游、防腐層 ACL、共享核心…)。
- 邊界也是團隊、部署(含微服務拆分)的自然切點。
🧪 我實際套用的紀錄
- 2026-07-14:(待填)
⚠️ 注意
- 別追求「一個統一大模型」——那通常是複雜度失控的來源。邊界內一致即可。
🔗 相關工具
- 工具-通用語言 —— 一體兩面,語言只在上下文內統一,邊界就是語意換軌的地方
- 工具-實體值物件與聚合 —— 往內一層,上下文之內再決定實體與聚合怎麼切
- 工具-管理複雜度 —— 為什麼要畫邊界,切開之後每次只需要理解一個上下文
🎯 什麼情境該想到我
當你要決定「一個微服務該多大、邊界畫在哪、從單體怎麼拆」時。
⚙️ 怎麼用
- 按業務能力/限界上下文切(見 工具-限界上下文),不按技術分層切。
- 檢驗好邊界:服務能獨立變更、獨立部署嗎?若一個改動總要同時改好幾個服務 → 邊界錯了。
- 每個服務擁有自己的資料:不共用資料庫,透過 API/事件互動(避免隱性耦合)。
- 服務間別太聊天:若兩服務呼叫極頻繁,可能該合併——高內聚該在同一服務內。
- 演進式拆分:從單體開始,沿著真實痛點與清楚的接縫逐步剝離(見 工具-架構隨業務規模演進)。
🧪 我實際套用的紀錄
- 2026-07-15:(待填)
⚠️ 注意
- 拆太細(nano-service)會讓網路呼叫、分散式事務、運維成本爆炸;寧可先粗再細。
🔗 相關工具
- 工具-限界上下文 —— DDD 版的同一件事,補上「怎麼從業務語言找出邊界」的方法
- 工具-康威定律 —— 現實限制,邊界畫得再漂亮,跟組織結構對不上就維持不住
- 工具-服務架構的演進與拆分 —— 姊妹卡,這張談邊界怎麼畫,它談什麼時候該拆、拆到什麼程度
👥 組織決定架構 康威定律
🎯 什麼情境該想到我
當你發現「系統架構總是長得像組織圖」、或跨團隊協作成本高到架構改不動時。
⚙️ 怎麼用
「設計系統的組織,其產出的架構會複製該組織的溝通結構。」
- 想要某種架構,先設計對應的團隊結構(逆康威):想要獨立的微服務,就要有能獨立負責的小團隊。
- 一個服務由一個團隊擁有:邊界對齊團隊,減少跨團隊的協調摩擦。
- 團隊之間的介面 = 服務之間的介面:把高頻溝通留在團隊內,團隊間走清楚的契約。
- 組織重組時,預期架構也會(該)跟著變。
🧪 我實際套用的紀錄
- 2026-07-15:(待填)
⚠️ 注意
- 強行讓架構違背組織溝通結構,通常會失敗或退化——架構與組織要一起設計。
🔗 相關工具
- 工具-服務邊界與演進式拆分 —— 直接推論,想改架構得先動組織,否則拆出來的服務還是照組織圖長
- 工具-限界上下文 —— 邊界的另一種畫法,康威從組織畫,限界上下文從業務語意畫,兩者最好對齊
- 工具-概念完整性 —— 反向約束,組織越分散越難維持一致的設計觀,需要刻意的架構治理
🌱 演進式拆分 先單體,痛了再拆
🎯 什麼情境該想到我
當你在猶豫「要不要從單體走向微服務、怎麼拆」,或被「微服務很潮」帶風向時。
⚙️ 怎麼用
- 認清各階段的取捨:單體(簡單、部署一體)→ SOA → 微服務(獨立部署/擴展,但引入分散式複雜度)→ 無伺服器。微服務不是免費的——你用開發簡單度換來運維與分散式的複雜度。
- 先具備前置條件再拆:自動化部署、監控、服務治理都到位,才適合微服務。
- 按業務邊界拆,而非技術分層——切點對齊 工具-限界上下文。
- 能單體就先單體(modular monolith),真的遇到擴展/團隊瓶頸再拆。
🧪 我實際套用的紀錄
- 2026-07-15:(待填)
⚠️ 注意
- 過早微服務化=把「函式呼叫」變成「網路呼叫」,換來分散式事務與除錯地獄。
🔗 相關工具
⚙️ 分散式的代價 容錯 × 事務 × 分流
🎯 什麼情境該想到我
當一個下游服務變慢/掛掉,就把整條鏈路甚至整個系統拖垮(雪崩)時。
⚙️ 怎麼用(組合使用)
- 熔斷(Circuit Breaker):偵測到下游持續失敗就「跳閘」,快速失敗、暫停呼叫,給它時間恢復,避免堆積。
- 艙壁隔離(Bulkhead):把資源(執行緒池/連線)按依賴分艙,一個依賴爆掉不會吃光全部資源。
- 重試 + 退避:對暫時性失敗重試,但要指數退避 + 上限 + 冪等,避免重試風暴(見 工具-MQ消費端防禦三原則)。
- 降級(Fallback):失敗時回傳合理的預設/快取結果,保住核心體驗。
- 流量控制(限流):超過容量就擋,保護系統不被打垮。
🧪 我實際套用的紀錄
- 2026-07-15:(待填)
⚠️ 注意
- 無腦重試是雪崩幫兇;重試前先確認「冪等 + 退避 + 熔斷」都到位。
🔗 相關工具
- 工具-MQ消費端防禦三原則 —— 非同步那一側的容錯,這張顧同步呼叫鏈,它顧訊息消費端
- 工具-防禦式編程 —— 更小顆粒的同一心態,容錯在服務層設界線,防禦式在函式層設界線
- 工具-透明多級分流 —— 上游配套,健康檢查與流量調度是熔斷之前就該擋掉問題的那一層
🎯 什麼情境該想到我
當一個業務動作要跨多個服務/資料庫、卻無法用單機交易保證「要嘛全成、要嘛全敗」時。
⚙️ 怎麼用(依一致性需求選方案,沒有銀彈)
- 可靠訊息佇列(本地訊息表 = Outbox):把業務寫入與事件記錄放同一本地交易,再由 relay 投遞 → 最終一致。最常用、最務實(見 工具-Transactional-Outbox-Pattern)。
- TCC(Try-Confirm-Cancel):業務層自己實作預留/確認/取消,強一致但侵入性高、開發成本大。
- Saga:把長交易拆成一連串本地交易 + 對應的補償動作,失敗就反向補償。適合長流程。
- 2PC/XA:強一致但同步阻塞、協調者單點,效能差,少用於高併發。
先問:這個場景需要強一致,還是最終一致就好?多數選最終一致(1)。
🧪 我實際套用的紀錄
- 2026-07-15:(待填)
⚠️ 注意
- 別預設「一定要強一致」;強一致代價很高。也別在 DB 交易內直接發 MQ。
🔗 相關工具
- 工具-Transactional-Outbox-Pattern —— 最常落地的一種實作:用本地交易+Outbox 換掉 2PC 的分散式鎖
- 工具-交易與隔離等級 —— 單機版的對照組,先懂單機保證了什麼,才知道跨服務失去了什麼
- 工具-MQ消費端防禦三原則 —— 走最終一致路線後的必要配套:consumer 必須能承受重複與亂序
🎯 什麼情境該想到我
當你在設計「使用者請求如何一路被導到正確、健康的服務節點」,或思考 CDN/負載均衡/網關該怎麼擺時。
⚙️ 怎麼用(一層層把流量導到對的地方,越前面擋掉越多越好)
- DNS:把網域解析到最近/可用的入口。
- CDN:靜態內容就近快取,別讓請求都打到源站。
- 負載均衡:把流量分散到多個健康節點(四層/七層)。
- API 網關:統一入口,做認證、限流、路由、聚合。
- 服務發現:讓呼叫端動態找到可用的服務實例(配合健康檢查)。
原則:能在越外層解決/擋掉的流量,就別讓它進到越內層,層層減壓。
🧪 我實際套用的紀錄
- 2026-07-15:(待填)
⚠️ 注意
- 每多一層都是複雜度與延遲;按實際規模採用,別一開始就全套。
🔗 相關工具
- 工具-服務容錯設計 —— 下一層防線,分流擋不住的故障靠熔斷與降級收尾
- 工具-資料分區 —— 更後面的瓶頸,前端流量分散了,資料層還是得自己切
- 工具-可靠可擴展可維護 —— 上位框架,分流同時服務可用性與可擴展兩個目標