架構模式快速參考指南

建構具有韌性、可擴展的分散式系統需要針對特定挑戰選擇正確的架構模式。本指南提供快速參考,幫助您根據問題領域選擇最合適的模式,並附上每個模式的詳細說明連結。

模式選擇快速參考

使用此表格快速識別哪個模式能解決您的特定挑戰:

您的挑戰建議模式使用時機
服務呼叫逾時非同步請求-回覆操作時間超過 HTTP 逾時限制
服務持續失敗斷路器防止無法使用的服務造成連鎖故障
暫時性網路故障重試處理快速恢復的暫時性故障
一個服務影響其他服務艙壁隔離資源以控制故障範圍
跨服務業務事務Saga 模式透過補償機制協調跨服務的長時事務
需要撤銷多步操作補償事務透過語意反向操作回滾跨服務的部分工作
突發流量壓垮服務基於佇列的負載均衡在生產者與消費者之間以佇列緩衝,平滑突發尖峰
本地寫入 + 事件發佈的原子性發件箱與本地資料庫交易一起保證事件可靠發佈
API 節流錯誤速率限制控制對節流服務的請求速率
舊系統整合防腐層保護乾淨架構免受舊系統影響
查詢效能緩慢具體化視圖預先計算複雜查詢以加快讀取速度
高頻重複讀取相同資料快取旁路按需將資料載入快取以緩解讀取壓力
需要按非主鍵欄位快速查找索引表為查詢頻繁的欄位建立二級索引
讀寫負載差異顯著CQRS分離讀模型與寫模型以獨立擴展
大型訊息負載提領檢查透過外部儲存資料來減少訊息大小
遷移舊系統絞殺者無花果逐步用現代系統取代舊系統
跨領域關注點側車在不修改應用程式的情況下新增功能
資料庫可擴展性分片將資料分散到多個資料庫
多個 API 呼叫閘道聚合將多個後端呼叫合併為一個
多個服務版本或端點閘道路由透過單一端點將請求路由到多個服務
事件分發發布-訂閱解耦事件生產者與消費者
服務健康監控健康端點監控主動偵測服務故障
需要單一協調者領導者選舉透過選舉一個實例為領導者來協調分散式工作
設定頻繁變更外部設定儲存在部署套件外集中管理設定
跨服務身份驗證聯合身份集中化身份驗證和授權

模式分類

架構模式可以根據它們解決的問題進行分組:

🛡️ 韌性模式

幫助系統優雅處理故障的模式: 斷路器:透過暫時阻止對失敗服務的呼叫來防止連鎖故障。就像電路斷路器一樣,當故障超過閾值時會「跳閘」,讓系統快速失敗並優雅恢復。 重試:自動重試失敗的操作以處理暫時性故障。使用指數退避等策略來避免壓垮已經承受壓力的服務。 艙壁:將資源隔離到獨立的池中,防止一個失敗的元件消耗所有資源。以船艙命名,用於控制進水。 Saga 模式:透過正向操作與補償操作,跨服務協調長時業務事務。與艙壁配套使用:艙壁隔離單一服務內部的故障;Saga 跨服務協調恢復。 [補償事務]:撤銷由一系列步驟共同完成的最終一致操作的工作。Saga 模式的基礎:每個 Saga 步驟都需要在後續步驟失敗時具備語意反向操作。 [基於佇列的負載均衡]:在任務與它呼叫的服務之間引入佇列作為緩衝,將任務與服務解耦。讓消費者按自身節奏處理,平滑突發重負載,防止節流並提升可用性。 [發件箱]:在業務寫入的同一本地交易中將待發佈訊息存入「發件箱」表,再由獨立進程讀取發件箱並發佈到訊息匯流排。解決當 Saga 事件必須與狀態變更原子性發出時的雙寫問題。

💡組合韌性模式

這些模式最好一起使用:重試處理暫時性故障,斷路器防止壓垮失敗的服務,艙壁控制故障的爆炸半徑。Saga 模式在跨服務場景下與之互補——協調能夠承受部分故障的多步事務。基於佇列的負載均衡在脆弱依賴上游吸收突發流量,發件箱保證 Saga 事件與本地資料庫交易可靠一同發佈。

⚡ 效能模式

優化系統效能和回應性的模式: 非同步請求-回覆:將長時間執行的操作與即時回應解耦,防止逾時並改善使用者體驗。 具體化視圖:預先計算並儲存查詢結果,避免在讀取時進行昂貴的計算。適合複雜的聚合和報表。 [快取旁路]:按需將資料從底層資料儲存載入到快取;應用程式優先從快取讀取,未命中則回退到資料儲存並回填快取。最常見的讀側優化——通常在考慮具體化視圖之前使用。 [索引表]:為資料儲存中查詢頻繁引用、但主鍵未覆蓋的欄位建立二級索引。當查詢模式具有選擇性時,比具體化視圖更易於建置和維護。 [CQRS]:將讀操作與寫操作分離為不同的模型(往往使用不同儲存)。讀側可獨立於寫側擴展,讀模型可以針對查詢速度進行反正規化,代價是寫側的最終一致性。 提領檢查:透過將大型資料儲存在外部並僅傳遞參考來減少訊息負載大小。改善訊息系統效能並降低成本。 分片:將資料分散到多個資料庫以提高可擴展性和效能。每個分片處理總資料的一個子集。

🔄 整合模式

促進系統間通訊的模式: 防腐層:在具有不同語義的系統之間提供轉換層,保護您的乾淨架構免受舊系統怪癖的影響。 閘道聚合:將多個後端服務呼叫合併為單一請求,減少客戶端複雜性和網路開銷。 [閘道路由]:透過單一端點將請求路由到多個服務之一。與閘道聚合和閘道卸載自然搭配,共同構成完整的 API 閘道。 發布-訂閱:啟用非同步事件驅動通訊,發布者不需要知道訂閱者。 聯合身份:將身份驗證委派給外部身份提供者,實現跨多個系統的單一登入。

🎯 營運模式

改善系統營運和管理的模式: 速率限制:控制發送到服務的請求速率,避免節流錯誤並優化吞吐量。 健康端點監控:公開健康檢查端點以進行主動監控和自動恢復。 側車:在應用程式旁部署輔助元件,處理日誌記錄、監控和配置等跨領域關注點。 [領導者選舉]:從一組分散式任務實例中選舉一個實例擔任領導者,由其協調其他實例的工作。適用於需要一個單一協調者(例如排程或分片分配)但沒有永久指定實例的場景。 [外部設定儲存]:將設定資訊從應用程式部署套件中移出,集中存放到獨立位置。讓設定能夠不重新部署即可變更,並支援環境特定值、特性開關和密鑰。

🏗️ 遷移模式

支援系統現代化的模式: 絞殺者無花果:透過逐步將功能遷移到新實作來逐步取代舊系統。以纏繞並最終取代宿主的無花果樹命名。

決策流程圖:選擇正確的模式

使用此流程圖導航到最適合您情況的模式:

graph TD Start[您的挑戰是什麼?] --> Q1{服務<br/>可用性?} Q1 -->|重複失敗| CB[斷路器] Q1 -->|暫時性故障| Retry[重試模式] Q1 -->|一個影響其他| Bulkhead[艙壁] Q1 -->|多服務協作| SagaNode[Saga] Q1 -->|需要撤銷操作| CT[補償事務] Q1 -->|突發流量| QBLL[基於佇列的負載均衡] Q1 -->|寫入+發佈原子性| OB[發件箱] Q1 -->|效能| Q2{什麼類型?} Q2 -->|長時間操作| Async[非同步請求-回覆] Q2 -->|查詢緩慢| MV[具體化視圖] Q2 -->|高頻讀取| CA[快取旁路] Q2 -->|按欄位查找| IT[索引表] Q2 -->|讀寫分離| CQRSNode[CQRS] Q2 -->|大型訊息| CC[提領檢查] Q2 -->|資料庫規模| Shard[分片] Q1 -->|整合| Q3{什麼需求?} Q3 -->|舊系統| ACL[防腐層] Q3 -->|多個呼叫| GA[閘道聚合] Q3 -->|多端點| GR[閘道路由] Q3 -->|事件分發| PubSub[發布-訂閱] Q3 -->|身份驗證| FI[聯合身份] Q1 -->|營運| Q4{什麼方面?} Q4 -->|節流| RL[速率限制] Q4 -->|監控| HEM[健康端點] Q4 -->|跨領域| Sidecar[側車] Q4 -->|單一協調者| LE[領導者選舉] Q4 -->|設定變更| ECS[外部設定儲存] Q1 -->|遷移| SF[絞殺者無花果] style CB fill:#ff6b6b style Retry fill:#ff6b6b style Bulkhead fill:#ff6b6b style SagaNode fill:#ff6b6b style CT fill:#ff6b6b style QBLL fill:#ff6b6b style OB fill:#ff6b6b style Async fill:#51cf66 style MV fill:#51cf66 style CA fill:#51cf66 style IT fill:#51cf66 style CQRSNode fill:#51cf66 style CC fill:#51cf66 style Shard fill:#51cf66 style ACL fill:#4dabf7 style GA fill:#4dabf7 style GR fill:#4dabf7 style PubSub fill:#4dabf7 style FI fill:#4dabf7 style RL fill:#ffd43b style HEM fill:#ffd43b style Sidecar fill:#ffd43b style LE fill:#ffd43b style ECS fill:#ffd43b style SF fill:#a78bfa

模式比較矩陣

跨關鍵維度比較模式:

{ "title": { "text": "模式複雜度 vs 影響" }, "tooltip": { "trigger": "item", "formatter": "{b}<br/>複雜度: {c0}<br/>影響: {c1}" }, "xAxis": { "type": "value", "name": "實作複雜度", "min": 0, "max": 10 }, "yAxis": { "type": "value", "name": "系統影響", "min": 0, "max": 10 }, "series": [{ "type": "scatter", "symbolSize": 20, "data": [ {"name": "重試", "value": [2, 7]}, {"name": "斷路器", "value": [4, 8]}, {"name": "艙壁", "value": [5, 8]}, {"name": "補償事務", "value": [5, 8]}, {"name": "基於佇列的負載均衡", "value": [5, 7]}, {"name": "發件箱", "value": [4, 7]}, {"name": "速率限制", "value": [6, 7]}, {"name": "防腐層", "value": [7, 9]}, {"name": "非同步請求-回覆", "value": [6, 8]}, {"name": "具體化視圖", "value": [5, 7]}, {"name": "快取旁路", "value": [3, 7]}, {"name": "索引表", "value": [4, 7]}, {"name": "CQRS", "value": [8, 9]}, {"name": "提領檢查", "value": [3, 6]}, {"name": "絞殺者無花果", "value": [8, 9]}, {"name": "側車", "value": [4, 6]}, {"name": "分片", "value": [9, 9]}, {"name": "閘道聚合", "value": [5, 7]}, {"name": "閘道路由", "value": [4, 7]}, {"name": "發布-訂閱", "value": [6, 8]}, {"name": "健康端點", "value": [2, 6]}, {"name": "領導者選舉", "value": [7, 7]}, {"name": "外部設定儲存", "value": [3, 6]}, {"name": "聯合身份", "value": [7, 8]}, {"name": "Saga 模式", "value": [7, 9]} ], "label": { "show": true, "position": "top", "formatter": "{b}" } }] }

模式組合

許多實際系統結合多個模式以提供全面的解決方案:

韌性微服務堆疊

這四個——斷路器重試艙壁健康端點——是「每一次同步服務間呼叫都被它們包著」這套經典集合。每個模式針對的都是其它三個解決不了的失敗模式,並按下圖順序分層:

模式針對的失敗模式分層
健康端點盲目運行——無法區分瞬時抖動和持續故障偵測(餵給其它三者)
斷路器連鎖故障——一個慢下游拖垮整張網保護(呼叫前的閘門)
重試瞬時抖動——網路抖動、GC 暫停、短時過載恢復(包住呼叫)
艙壁資源飢餓——一個吵鬧鄰居耗盡共享資源隔離(每個下游的資源上限)
flowchart TB Caller[呼叫端] Caller --> Bulkhead[艙壁<br/>為各下游限制執行緒池] Bulkhead --> Breaker{斷路器<br/>開 / 半開 / 關} Breaker -->|關| Retry[重試迴圈<br/>指數退避<br/>冪等] Retry --> Call[服務呼叫] Breaker -->|開| FailFast[快速失敗] Health[健康端點<br/>由監控探測] Health -.餵給狀態.-> Breaker style Bulkhead fill:#c8e6c9 style Breaker fill:#fff9c4 style Retry fill:#e1f5ff style Health fill:#f5f5f5

從內往外讀:艙壁給這個下游設了資源上限;斷路器決定要不要繼續;重試在閉合迴圈裡處理每次呼叫的瞬時抖動;健康端點由監控輪詢,餵給斷路器狀態機的訊號。

  • 斷路器:防止連鎖故障
  • 重試:處理暫時性故障
  • 艙壁:隔離資源
  • 健康端點:啟用監控

高效能 API 閘道

這三個——速率限制閘道聚合非同步請求-回覆——構成「高吞吐量公開 API 邊緣」的經典集合。每個模式針對的都是其它兩個解決不了的關注點:拒絕、組合還是時延緩解。它們沿請求流分層,如下圖所示:

模式針對的失敗模式在請求流中的位置
速率限制後端過載——行為異常的客戶端或突發流量打掛上游入口閘門(先拒絕再做事)
閘道聚合客戶端來回過多——每次一屏要 N 次往返,行動端和弱網環境尤其痛苦組合(扇出再合併)
非同步請求-回覆阻塞——一次慢下游呼叫就卡住執行緒並佔住一條客戶端連線時延緩解(慢呼叫回傳 202 + 輪詢令牌)
flowchart TB Client[客戶端] Client --> RL[速率限制<br/>按客戶端限額<br/>先拒後放] RL --> GA[閘道聚合<br/>扇出 N 個呼叫<br/>合併為 1 個回應] GA -->|快速呼叫<br/>同步| Sync[同步處理<br/>立即回應] GA -->|慢速呼叫<br/>> 閾值| Async[非同步請求-回覆<br/>202 + 輪詢令牌<br/>Claim-Check 風格] Sync --> Backends[後端] Async --> Backends style RL fill:#ffcdd2 style GA fill:#c8e6c9 style Async fill:#e1f5ff

從上往下讀這張圖:速率限制是最外層閘門——先拒絕,絕不讓惡意流量到達組合層;閘道聚合再把一次客戶端請求扇出到 N 個後端呼叫並合併結果。如果任何一次聚合呼叫會超出時延預算,非同步請求-回覆就改回傳輪詢令牌,不再阻塞客戶端。

  • 速率限制:在請求到達組合層之前就先拒掉多餘的流量
  • 閘道聚合:扇出再合併,讓客戶端只做一次往返
  • 非同步請求-回覆:對會阻塞太久的呼叫回傳 202 + 令牌

舊系統現代化

這三個——聯合身份絞殺者無花果防腐層——構成「不搞大爆炸重寫就能擺脫舊單體」的經典集合。每個模式針對的都是一種獨立風險:遷移之前先統一登入入口,然後是遷移路由器本身,最後是新舊契約之間的翻譯。它們沿請求流分層,如下圖所示:

模式針對的失敗模式在請求流中的位置
聯合身份每個子系統各自登入——每遷移一個就發明一套身份,登入體驗碎成渣邊界(邊緣唯一的身份入口)
絞殺者無花果大爆炸重寫風險——舊系統仍在生產,新程式碼只能一片一片上路由器(按功能切流量)
防腐層舊系統污染——新領域模型把老契約裡的怪癖全吸進來翻譯(舊模型 → 新領域)
flowchart TB User[使用者 / 客戶端] User --> FID[聯合身份<br/>統一身份邊界<br/>SSO + 令牌交換] FID --> SF[絞殺者無花果<br/>按功能路由<br/>舊路徑 vs 新路徑] SF -->|已遷移功能| NewSvc[新微服務<br/>乾淨領域] SF -->|未遷移功能| Legacy[舊系統] Legacy --> ACL[防腐層<br/>翻譯舊模型<br/>到新領域] ACL --> NewSvc style FID fill:#fff9c4 style SF fill:#c8e6c9 style ACL fill:#f8bbd0 style NewSvc fill:#e1f5ff style Legacy fill:#f5f5f5

從上往下讀這張圖:聯合身份在邊緣立起唯一身份邊界,使用者從舊到新切換子系統時不必再走一遍登入。絞殺者無花果按功能切流量——已遷移的路徑直接進新服務;未遷移的仍走舊系統,但先經過防腐層把舊契約翻成新領域再交給新服務。新服務從來不直接講舊協定。

  • 聯合身份:貫穿新舊系統的統一身份邊界
  • 絞殺者無花果:按功能切流量,讓遷移可以一步步推進
  • 防腐層:把舊契約翻譯成新領域模型

彈性分散式事務

這三個——發件箱Saga 模式斷路器——構成「多服務事務在部分失敗中存活下來、且不會丟事件」的經典集合。每個模式針對的都是一種獨立災害:本地原子寫入、跨服務協調、每次步進的保護。它們沿時序流分層,如下圖所示:

模式針對的失敗模式在流程中的位置
發件箱雙寫異常——DB 已提交但事件沒發出去(或反過來),狀態與訊息巴士上不一致寫入階段(事件隨本地 DB 提交原子落地)
Saga 模式跨服務不可能 ACID——多服務之間沒有全域交易,部分失敗會留下懸掛狀態協調(前進步驟 + 語意反向)
斷路器Saga 步進過載——慢參與者卡住協調器,整條後續鏈路停擺單步保護(封住每次呼叫的爆炸半徑)
flowchart TB Tx[本地 DB 交易<br/>業務寫入 +<br/>發件箱列追加] Tx --> Relay[發件箱中繼<br/>輪詢或日誌尾隨<br/>發到訊息巴士] Relay --> Bus[訊息巴士] Bus --> Orch[Saga 協調器] Orch --> CB{斷路器<br/>關 / 半 / 開} CB -->|關| Step[Saga 步進呼叫<br/>到參與者服務] CB -->|開| FailFast[快速失敗<br/>標記步驟可重試] Step --> SDb[(參與者資料庫<br/>自身提交)] SDb -.發出下一步事件.-> Bus style Tx fill:#fff9c4 style Relay fill:#f8bbd0 style Orch fill:#c8e6c9 style CB fill:#e1f5ff

從上往下讀這張圖:本地 DB 交易把業務狀態和發件箱列放在同一次原子提交裡,狀態與待發事件從此不再失同步;發件箱中繼把發件箱列讀出來發到訊息巴士;Saga 協調器消費這些事件,發出下一步,而每一步呼叫都被斷路器守住,這樣一個掛掉的參與者不會把整條 Saga 拖住。

  • 發件箱:保證事件與本地 DB 交易一起可靠發佈
  • Saga 模式:用前向與補償動作協調跨服務交易
  • 斷路器:封住每次 Saga 步進的下游呼叫爆炸半徑

模式選擇標準

選擇模式時考慮這些因素:

系統需求

📝功能需求

  • 可用性:可接受多少停機時間?
  • 效能:您的延遲需求是什麼?
  • 可擴展性:您預期多少成長?
  • 一致性:您需要什麼一致性保證?

技術限制

📝技術因素

  • 現有基礎設施:已經有哪些系統?
  • 團隊專業知識:您的團隊了解哪些模式?
  • 技術堆疊:有哪些框架和函式庫可用?
  • 預算:您可以分配哪些資源?

營運考量

📝營運

  • 監控:您能觀察模式的行為嗎?
  • 維護:持續維護有多複雜?
  • 測試:您能有效測試實作嗎?
  • 文件:模式是否有良好的文件?

常見反模式

應用模式時避免這些常見錯誤:

⚠️模式誤用

過度工程:不要將複雜的模式應用於簡單的問題。從簡單開始,根據需要添加模式。 模式堆疊:避免在沒有明確理由的情況下組合太多模式。每個模式都會增加複雜性。 忽略權衡:每個模式都有成本。考慮效能開銷、營運複雜性和維護負擔。 貨物崇拜實作:不要在不理解模式為何有效的情況下複製模式。根據您的特定情境調整模式。 有關程式碼層級反模式(如上帝物件、貨物崇拜程式設計和複製貼上程式設計)的全面指南,請參閱軟體開發反模式

入門指南

實作模式時遵循此方法:

1. 識別問題

清楚定義您試圖解決的挑戰:

  • 您遇到什麼症狀?
  • 根本原因是什麼?
  • 您的成功標準是什麼?

2. 研究模式

使用本指南識別候選模式:

  • 查看快速參考表
  • 遵循決策流程圖
  • 閱讀詳細的模式文章

3. 評估選項

根據您的需求比較模式:

  • 實作複雜度
  • 營運開銷
  • 團隊專業知識
  • 預算限制

4. 從小處開始

從試點實作開始:

  • 選擇非關鍵元件
  • 實作模式
  • 監控和測量結果
  • 根據學習進行迭代

5. 逐步擴展

擴展成功的實作:

  • 記錄經驗教訓
  • 培訓團隊成員
  • 應用於其他元件
  • 根據經驗改進

完整模式索引

以下是本系列涵蓋的完整模式列表:

  1. 速率限制模式(一月)- 控制對節流服務的請求速率
  2. 防腐層模式(二月)- 保護架構免受舊系統影響
  3. 重試模式(三月)- 優雅處理暫時性故障
  4. 提領檢查模式(四月)- 減少訊息負載大小
  5. 具體化視圖模式(五月)- 預先計算複雜查詢
  6. 絞殺者無花果模式(六月)- 逐步遷移舊系統
  7. 側車模式(七月)- 透過輔助元件新增功能
  8. 分片模式(八月)- 分散資料以提高可擴展性
  9. 閘道聚合模式(九月)- 合併多個 API 呼叫
  10. 發布-訂閱模式(十月)- 事件驅動通訊
  11. 健康端點監控模式(十一月)- 主動健康檢查
  12. 聯合身份模式(十二月)- 集中化身份驗證
  13. 斷路器模式(一月)- 防止連鎖故障
  14. 艙壁模式(三月)- 隔離資源以控制故障
  15. 非同步請求-回覆模式(四月)- 處理長時間執行的操作
  16. Saga 模式(七月)- 透過補償機制協調跨服務的事務
  17. 補償事務 - 撤銷由一系列步驟共同完成的最終一致操作的工作
  18. 基於佇列的負載均衡 - 在任務與服務之間以佇列作為緩衝,平滑間歇性重負載
  19. 發件箱 - 將待發佈訊息存入本地交易的發件箱表,由獨立進程可靠發佈
  20. 快取旁路 - 按需將資料從底層資料儲存載入到快取
  21. 索引表 - 為資料儲存中查詢頻繁引用的欄位建立二級索引
  22. CQRS - 分離讀操作與寫操作為不同模型以獨立擴展
  23. 閘道路由 - 透過單一端點將請求路由到多個服務之一
  24. 領導者選舉 - 透過選舉一個實例為領導者來協調分散式工作
  25. 外部設定儲存 - 將設定資訊移出應用程式部署套件,集中存放到獨立位置

其他資源

書籍

  • “Cloud Design Patterns” by Microsoft - 全面的模式目錄
  • “Release It!” by Michael Nygard - 生產就緒軟體模式
  • “Building Microservices” by Sam Newman - 微服務架構模式
  • “Domain-Driven Design” by Eric Evans - 策略設計模式

線上資源

實踐

💡從實作中學習

學習模式的最佳方式是透過實作練習:

  • 建構實作每個模式的範例應用程式
  • 為使用這些模式的開源專案做出貢獻
  • 與您的團隊進行架構審查
  • 透過部落格文章和簡報分享知識

結論

架構模式是解決常見分散式系統挑戰的強大工具。本快速參考指南幫助您:

  • 快速識別適合您問題的正確模式
  • 比較模式跨多個維度
  • 理解關係模式之間的關係
  • 避免常見陷阱在模式應用中
  • 規劃您的學習透過模式目錄的旅程 記住:模式是指南,不是僵化的規則。根據您的特定情境調整它們,測量它們的影響,並根據結果進行迭代。從簡單的模式如重試和健康端點監控開始,然後隨著系統的發展逐步採用更複雜的模式。

留言

請接受「功能性」Cookie 類別以查看和發表留言。