建構具有韌性、可擴展的分散式系統需要針對特定挑戰選擇正確的架構模式。本指南提供快速參考,幫助您根據問題領域選擇最合適的模式,並附上每個模式的詳細說明連結。
模式選擇快速參考
使用此表格快速識別哪個模式能解決您的特定挑戰:
| 您的挑戰 | 建議模式 | 使用時機 |
|---|---|---|
| 服務呼叫逾時 | 非同步請求-回覆 | 操作時間超過 HTTP 逾時限制 |
| 服務持續失敗 | 斷路器 | 防止無法使用的服務造成連鎖故障 |
| 暫時性網路故障 | 重試 | 處理快速恢復的暫時性故障 |
| 一個服務影響其他服務 | 艙壁 | 隔離資源以控制故障範圍 |
| 跨服務業務事務 | Saga 模式 | 透過補償機制協調跨服務的長時事務 |
| 需要撤銷多步操作 | 補償事務 | 透過語意反向操作回滾跨服務的部分工作 |
| 突發流量壓垮服務 | 基於佇列的負載均衡 | 在生產者與消費者之間以佇列緩衝,平滑突發尖峰 |
| 本地寫入 + 事件發佈的原子性 | 發件箱 | 與本地資料庫交易一起保證事件可靠發佈 |
| API 節流錯誤 | 速率限制 | 控制對節流服務的請求速率 |
| 舊系統整合 | 防腐層 | 保護乾淨架構免受舊系統影響 |
| 查詢效能緩慢 | 具體化視圖 | 預先計算複雜查詢以加快讀取速度 |
| 高頻重複讀取相同資料 | 快取旁路 | 按需將資料載入快取以緩解讀取壓力 |
| 需要按非主鍵欄位快速查找 | 索引表 | 為查詢頻繁的欄位建立二級索引 |
| 讀寫負載差異顯著 | CQRS | 分離讀模型與寫模型以獨立擴展 |
| 大型訊息負載 | 提領檢查 | 透過外部儲存資料來減少訊息大小 |
| 遷移舊系統 | 絞殺者無花果 | 逐步用現代系統取代舊系統 |
| 跨領域關注點 | 側車 | 在不修改應用程式的情況下新增功能 |
| 資料庫可擴展性 | 分片 | 將資料分散到多個資料庫 |
| 多個 API 呼叫 | 閘道聚合 | 將多個後端呼叫合併為一個 |
| 多個服務版本或端點 | 閘道路由 | 透過單一端點將請求路由到多個服務 |
| 事件分發 | 發布-訂閱 | 解耦事件生產者與消費者 |
| 服務健康監控 | 健康端點監控 | 主動偵測服務故障 |
| 需要單一協調者 | 領導者選舉 | 透過選舉一個實例為領導者來協調分散式工作 |
| 設定頻繁變更 | 外部設定儲存 | 在部署套件外集中管理設定 |
| 跨服務身份驗證 | 聯合身份 | 集中化身份驗證和授權 |
模式分類
架構模式可以根據它們解決的問題進行分組:
🛡️ 韌性模式
幫助系統優雅處理故障的模式: 斷路器:透過暫時阻止對失敗服務的呼叫來防止連鎖故障。就像電路斷路器一樣,當故障超過閾值時會「跳閘」,讓系統快速失敗並優雅恢復。 重試:自動重試失敗的操作以處理暫時性故障。使用指數退避等策略來避免壓垮已經承受壓力的服務。 艙壁:將資源隔離到獨立的池中,防止一個失敗的元件消耗所有資源。以船艙命名,用於控制進水。 Saga 模式:透過正向操作與補償操作,跨服務協調長時業務事務。與艙壁配套使用:艙壁隔離單一服務內部的故障;Saga 跨服務協調恢復。 [補償事務]:撤銷由一系列步驟共同完成的最終一致操作的工作。Saga 模式的基礎:每個 Saga 步驟都需要在後續步驟失敗時具備語意反向操作。 [基於佇列的負載均衡]:在任務與它呼叫的服務之間引入佇列作為緩衝,將任務與服務解耦。讓消費者按自身節奏處理,平滑突發重負載,防止節流並提升可用性。 [發件箱]:在業務寫入的同一本地交易中將待發佈訊息存入「發件箱」表,再由獨立進程讀取發件箱並發佈到訊息匯流排。解決當 Saga 事件必須與狀態變更原子性發出時的雙寫問題。
組合韌性模式
這些模式最好一起使用:重試處理暫時性故障,斷路器防止壓垮失敗的服務,艙壁控制故障的爆炸半徑。Saga 模式在跨服務場景下與之互補——協調能夠承受部分故障的多步事務。基於佇列的負載均衡在脆弱依賴上游吸收突發流量,發件箱保證 Saga 事件與本地資料庫交易可靠一同發佈。
⚡ 效能模式
優化系統效能和回應性的模式: 非同步請求-回覆:將長時間執行的操作與即時回應解耦,防止逾時並改善使用者體驗。 具體化視圖:預先計算並儲存查詢結果,避免在讀取時進行昂貴的計算。適合複雜的聚合和報表。 [快取旁路]:按需將資料從底層資料儲存載入到快取;應用程式優先從快取讀取,未命中則回退到資料儲存並回填快取。最常見的讀側優化——通常在考慮具體化視圖之前使用。 [索引表]:為資料儲存中查詢頻繁引用、但主鍵未覆蓋的欄位建立二級索引。當查詢模式具有選擇性時,比具體化視圖更易於建置和維護。 [CQRS]:將讀操作與寫操作分離為不同的模型(往往使用不同儲存)。讀側可獨立於寫側擴展,讀模型可以針對查詢速度進行反正規化,代價是寫側的最終一致性。 提領檢查:透過將大型資料儲存在外部並僅傳遞參考來減少訊息負載大小。改善訊息系統效能並降低成本。 分片:將資料分散到多個資料庫以提高可擴展性和效能。每個分片處理總資料的一個子集。
🔄 整合模式
促進系統間通訊的模式: 防腐層:在具有不同語義的系統之間提供轉換層,保護您的乾淨架構免受舊系統怪癖的影響。 閘道聚合:將多個後端服務呼叫合併為單一請求,減少客戶端複雜性和網路開銷。 [閘道路由]:透過單一端點將請求路由到多個服務之一。與閘道聚合和閘道卸載自然搭配,共同構成完整的 API 閘道。 發布-訂閱:啟用非同步事件驅動通訊,發布者不需要知道訂閱者。 聯合身份:將身份驗證委派給外部身份提供者,實現跨多個系統的單一登入。
🎯 營運模式
改善系統營運和管理的模式: 速率限制:控制發送到服務的請求速率,避免節流錯誤並優化吞吐量。 健康端點監控:公開健康檢查端點以進行主動監控和自動恢復。 側車:在應用程式旁部署輔助元件,處理日誌記錄、監控和配置等跨領域關注點。 [領導者選舉]:從一組分散式任務實例中選舉一個實例擔任領導者,由其協調其他實例的工作。適用於需要一個單一協調者(例如排程或分片分配)但沒有永久指定實例的場景。 [外部設定儲存]:將設定資訊從應用程式部署套件中移出,集中存放到獨立位置。讓設定能夠不重新部署即可變更,並支援環境特定值、特性開關和密鑰。
🏗️ 遷移模式
支援系統現代化的模式: 絞殺者無花果:透過逐步將功能遷移到新實作來逐步取代舊系統。以纏繞並最終取代宿主的無花果樹命名。
決策流程圖:選擇正確的模式
使用此流程圖導航到最適合您情況的模式:
模式比較矩陣
跨關鍵維度比較模式:
模式組合
許多實際系統結合多個模式以提供全面的解決方案:
韌性微服務堆疊
這四個——斷路器、重試、艙壁、健康端點——是「每一次同步服務間呼叫都被它們包著」這套經典集合。每個模式針對的都是其它三個解決不了的失敗模式,並按下圖順序分層:
| 模式 | 針對的失敗模式 | 分層 |
|---|---|---|
| 健康端點 | 盲目運行——無法區分瞬時抖動和持續故障 | 偵測(餵給其它三者) |
| 斷路器 | 連鎖故障——一個慢下游拖垮整張網 | 保護(呼叫前的閘門) |
| 重試 | 瞬時抖動——網路抖動、GC 暫停、短時過載 | 恢復(包住呼叫) |
| 艙壁 | 資源飢餓——一個吵鬧鄰居耗盡共享資源 | 隔離(每個下游的資源上限) |
從內往外讀:艙壁給這個下游設了資源上限;斷路器決定要不要繼續;重試在閉合迴圈裡處理每次呼叫的瞬時抖動;健康端點由監控輪詢,餵給斷路器狀態機的訊號。
- 斷路器:防止連鎖故障
- 重試:處理暫時性故障
- 艙壁:隔離資源
- 健康端點:啟用監控
高效能 API 閘道
這三個——速率限制、閘道聚合與非同步請求-回覆——構成「高吞吐量公開 API 邊緣」的經典集合。每個模式針對的都是其它兩個解決不了的關注點:拒絕、組合還是時延緩解。它們沿請求流分層,如下圖所示:
| 模式 | 針對的失敗模式 | 在請求流中的位置 |
|---|---|---|
| 速率限制 | 後端過載——行為異常的客戶端或突發流量打掛上游 | 入口閘門(先拒絕再做事) |
| 閘道聚合 | 客戶端來回過多——每次一屏要 N 次往返,行動端和弱網環境尤其痛苦 | 組合(扇出再合併) |
| 非同步請求-回覆 | 阻塞——一次慢下游呼叫就卡住執行緒並佔住一條客戶端連線 | 時延緩解(慢呼叫回傳 202 + 輪詢令牌) |
從上往下讀這張圖:速率限制是最外層閘門——先拒絕,絕不讓惡意流量到達組合層;閘道聚合再把一次客戶端請求扇出到 N 個後端呼叫並合併結果。如果任何一次聚合呼叫會超出時延預算,非同步請求-回覆就改回傳輪詢令牌,不再阻塞客戶端。
- 速率限制:在請求到達組合層之前就先拒掉多餘的流量
- 閘道聚合:扇出再合併,讓客戶端只做一次往返
- 非同步請求-回覆:對會阻塞太久的呼叫回傳 202 + 令牌
舊系統現代化
這三個——聯合身份、絞殺者無花果與防腐層——構成「不搞大爆炸重寫就能擺脫舊單體」的經典集合。每個模式針對的都是一種獨立風險:遷移之前先統一登入入口,然後是遷移路由器本身,最後是新舊契約之間的翻譯。它們沿請求流分層,如下圖所示:
| 模式 | 針對的失敗模式 | 在請求流中的位置 |
|---|---|---|
| 聯合身份 | 每個子系統各自登入——每遷移一個就發明一套身份,登入體驗碎成渣 | 邊界(邊緣唯一的身份入口) |
| 絞殺者無花果 | 大爆炸重寫風險——舊系統仍在生產,新程式碼只能一片一片上 | 路由器(按功能切流量) |
| 防腐層 | 舊系統污染——新領域模型把老契約裡的怪癖全吸進來 | 翻譯(舊模型 → 新領域) |
從上往下讀這張圖:聯合身份在邊緣立起唯一身份邊界,使用者從舊到新切換子系統時不必再走一遍登入。絞殺者無花果按功能切流量——已遷移的路徑直接進新服務;未遷移的仍走舊系統,但先經過防腐層把舊契約翻成新領域再交給新服務。新服務從來不直接講舊協定。
- 聯合身份:貫穿新舊系統的統一身份邊界
- 絞殺者無花果:按功能切流量,讓遷移可以一步步推進
- 防腐層:把舊契約翻譯成新領域模型
彈性分散式事務
這三個——發件箱、Saga 模式與斷路器——構成「多服務事務在部分失敗中存活下來、且不會丟事件」的經典集合。每個模式針對的都是一種獨立災害:本地原子寫入、跨服務協調、每次步進的保護。它們沿時序流分層,如下圖所示:
| 模式 | 針對的失敗模式 | 在流程中的位置 |
|---|---|---|
| 發件箱 | 雙寫異常——DB 已提交但事件沒發出去(或反過來),狀態與訊息巴士上不一致 | 寫入階段(事件隨本地 DB 提交原子落地) |
| Saga 模式 | 跨服務不可能 ACID——多服務之間沒有全域交易,部分失敗會留下懸掛狀態 | 協調(前進步驟 + 語意反向) |
| 斷路器 | Saga 步進過載——慢參與者卡住協調器,整條後續鏈路停擺 | 單步保護(封住每次呼叫的爆炸半徑) |
從上往下讀這張圖:本地 DB 交易把業務狀態和發件箱列放在同一次原子提交裡,狀態與待發事件從此不再失同步;發件箱中繼把發件箱列讀出來發到訊息巴士;Saga 協調器消費這些事件,發出下一步,而每一步呼叫都被斷路器守住,這樣一個掛掉的參與者不會把整條 Saga 拖住。
- 發件箱:保證事件與本地 DB 交易一起可靠發佈
- Saga 模式:用前向與補償動作協調跨服務交易
- 斷路器:封住每次 Saga 步進的下游呼叫爆炸半徑
模式選擇標準
選擇模式時考慮這些因素:
系統需求
功能需求
- 可用性:可接受多少停機時間?
- 效能:您的延遲需求是什麼?
- 可擴展性:您預期多少成長?
- 一致性:您需要什麼一致性保證?
技術限制
技術因素
- 現有基礎設施:已經有哪些系統?
- 團隊專業知識:您的團隊了解哪些模式?
- 技術堆疊:有哪些框架和函式庫可用?
- 預算:您可以分配哪些資源?
營運考量
營運
- 監控:您能觀察模式的行為嗎?
- 維護:持續維護有多複雜?
- 測試:您能有效測試實作嗎?
- 文件:模式是否有良好的文件?
常見反模式
應用模式時避免這些常見錯誤:
模式誤用
過度工程:不要將複雜的模式應用於簡單的問題。從簡單開始,根據需要添加模式。 模式堆疊:避免在沒有明確理由的情況下組合太多模式。每個模式都會增加複雜性。 忽略權衡:每個模式都有成本。考慮效能開銷、營運複雜性和維護負擔。 貨物崇拜實作:不要在不理解模式為何有效的情況下複製模式。根據您的特定情境調整模式。 有關程式碼層級反模式(如上帝物件、貨物崇拜程式設計和複製貼上程式設計)的全面指南,請參閱軟體開發反模式。
入門指南
實作模式時遵循此方法:
1. 識別問題
清楚定義您試圖解決的挑戰:
- 您遇到什麼症狀?
- 根本原因是什麼?
- 您的成功標準是什麼?
2. 研究模式
使用本指南識別候選模式:
- 查看快速參考表
- 遵循決策流程圖
- 閱讀詳細的模式文章
3. 評估選項
根據您的需求比較模式:
- 實作複雜度
- 營運開銷
- 團隊專業知識
- 預算限制
4. 從小處開始
從試點實作開始:
- 選擇非關鍵元件
- 實作模式
- 監控和測量結果
- 根據學習進行迭代
5. 逐步擴展
擴展成功的實作:
- 記錄經驗教訓
- 培訓團隊成員
- 應用於其他元件
- 根據經驗改進
完整模式索引
以下是本系列涵蓋的完整模式列表:
- 速率限制模式(一月)- 控制對節流服務的請求速率
- 防腐層模式(二月)- 保護架構免受舊系統影響
- 重試模式(三月)- 優雅處理暫時性故障
- 提領檢查模式(四月)- 減少訊息負載大小
- 具體化視圖模式(五月)- 預先計算複雜查詢
- 絞殺者無花果模式(六月)- 逐步遷移舊系統
- 側車模式(七月)- 透過輔助元件新增功能
- 分片模式(八月)- 分散資料以提高可擴展性
- 閘道聚合模式(九月)- 合併多個 API 呼叫
- 發布-訂閱模式(十月)- 事件驅動通訊
- 健康端點監控模式(十一月)- 主動健康檢查
- 聯合身份模式(十二月)- 集中化身份驗證
- 斷路器模式(一月)- 防止連鎖故障
- 艙壁模式(三月)- 隔離資源以控制故障
- 非同步請求-回覆模式(四月)- 處理長時間執行的操作
- Saga 模式(七月)- 透過補償機制協調跨服務的事務
- 補償事務 - 撤銷由一系列步驟共同完成的最終一致操作的工作
- 基於佇列的負載均衡 - 在任務與服務之間以佇列作為緩衝,平滑間歇性重負載
- 發件箱 - 將待發佈訊息存入本地交易的發件箱表,由獨立進程可靠發佈
- 快取旁路 - 按需將資料從底層資料儲存載入到快取
- 索引表 - 為資料儲存中查詢頻繁引用的欄位建立二級索引
- CQRS - 分離讀操作與寫操作為不同模型以獨立擴展
- 閘道路由 - 透過單一端點將請求路由到多個服務之一
- 領導者選舉 - 透過選舉一個實例為領導者來協調分散式工作
- 外部設定儲存 - 將設定資訊移出應用程式部署套件,集中存放到獨立位置
其他資源
書籍
- “Cloud Design Patterns” by Microsoft - 全面的模式目錄
- “Release It!” by Michael Nygard - 生產就緒軟體模式
- “Building Microservices” by Sam Newman - 微服務架構模式
- “Domain-Driven Design” by Eric Evans - 策略設計模式
線上資源
實踐
從實作中學習
學習模式的最佳方式是透過實作練習:
- 建構實作每個模式的範例應用程式
- 為使用這些模式的開源專案做出貢獻
- 與您的團隊進行架構審查
- 透過部落格文章和簡報分享知識
結論
架構模式是解決常見分散式系統挑戰的強大工具。本快速參考指南幫助您:
- 快速識別適合您問題的正確模式
- 比較模式跨多個維度
- 理解關係模式之間的關係
- 避免常見陷阱在模式應用中
- 規劃您的學習透過模式目錄的旅程 記住:模式是指南,不是僵化的規則。根據您的特定情境調整它們,測量它們的影響,並根據結果進行迭代。從簡單的模式如重試和健康端點監控開始,然後隨著系統的發展逐步採用更複雜的模式。
留言
請接受「功能性」Cookie 類別以查看和發表留言。
留言載入失敗。您可以重試,或前往 GitHub 查看討論。
在 GitHub 上查看