Circuit Breaker

在軟體系統中,「斷路器」是一種保護機制,用來避免系統在發生連續錯誤時被拖垮。它的核心目標是當外部服務或資源連續失敗時,暫時中斷請求,讓系統有時間恢復
家裡的電路,如果有電器短路,會造成電流暴增。斷路器就會「跳電」,暫時切斷電力,避免整個家被燒掉。在軟體中也是一樣,如果外部 API 一直回錯誤(例如 Timeout 或 500 Error),我們不應該一再重試,否則會耗盡 Thread、CPU、甚至把整個應用拖慢。所以斷路器會「跳閘」,暫停對那個外部服務的呼叫一段時間
| 狀態 | 意義 | 行為 |
|---|---|---|
| Closed(關閉) | 一切正常 | 請求會照常發送。如果有失敗,會記錄下來。 |
| Open(開啟) | 外部服務被認定「壞掉」 | 直接阻擋呼叫,立即回錯誤,不再嘗試。 |
| Half-Open(半開啟) | 試探階段 | 過一段時間後,允許少量請求試試看服務是否恢復。成功就恢復 Closed。 |
Polly
1 | using Polly; |
Handle<HttpRequestException>()- 告訴 Polly:只要發生這類錯誤,就記錄一次「失敗」。CircuitBreakerAsync(3, TimeSpan.FromSeconds(10))- 如果連續錯誤達 3 次,進入 Open 狀態,
接下來 10 秒內所有呼叫都會被拒絕。BrokenCircuitException- 表示斷路器已打開(跳閘),呼叫被攔截。過了 10 秒後,自動進入 Half-Open,允許幾次試探性呼叫。如果成功 → 回到 Closed;失敗 → 繼續 Open
怎麼設計
- 設定閾值(多少次錯誤才跳閘)
- 設定冷卻時間(多久再試)
- 處理不同錯誤型態(例如 Timeout、500、DNS 問題等)
啟動依據
CPU / 記憶體使用率(Resource Usage-Based)
請求失敗率(Error Rate-Based)
延遲時間過長(Latency-Based)
關鍵功能(如:結帳流程、購物車):以延遲時間與錯誤率為主,迅速啟動斷路器,以免使用者「卡在」付款頁
次要功能(如:商品推薦、即時聊天、評價讀取):以資源用量為主,在資源吃緊時主動關閉,保護核心流程順暢
另外也可以設計一個漸進式降級策略:例如先關閉圖片載入,再關閉推薦,最後才進入維護模式
次要、切換順序?
如果斷路器(Circuit Breaker)被錯誤地套用在太多功能上,可能導致使用者體驗下降。例如,推薦商品或庫存查詢被暫時中斷,是否仍會影響轉換率?這需要明確的優先級策略
斷路器觸發後,使用者看到的是什麼?
雖然技術上避免了系統崩潰,但如果介面只顯示錯誤或空白,使用者仍會覺得系統不穩。設計上需思考「優雅降級」或「替代內容」的體驗策略
斷路器的閾值如何設定?是靜態還是動態?
若閾值設定過低,容易誤觸造成服務中斷;過高則失去保護效果。這反映了技術設計與實際流量行為間的矛盾,需要動態監控與自我調整機制
| 類型 | 說明 | 優點 | 缺點 |
|---|---|---|---|
| 靜態閾值 | 事先寫死在設定中,例如「錯誤率超過 50% 就觸發」 | 簡單、可預測 | 不能自我調整,遇到流量暴增可能過於敏感或遲鈍 |
| 動態閾值 | 根據實際流量或系統負載自動調整,例如用滑動平均、AI 或監控資料計算 | 彈性高、適應性強 | 較複雜、需要監控與演算法支援 |
滑動時間窗口(Sliding Window)
系統不看全部歷史,而只看最近一段時間(例如最近 1 分鐘或 100 次請求)來動態估算失敗率或延遲。
failureRateThreshold: 動態 = (最近100次呼叫失敗率)
slowCallRateThreshold: 動態 = (最近10秒內慢呼叫比例)
🔹 優點:隨著流量波動自動調整,對電商高峰期特別有用。
🔹 缺點:需監控即時指標,運算略複雜。
基於「統計分佈」的閾值(Percentile-based)
不是看平均值,而是根據分佈百分位(如 p95、p99)設定閾值。
例如:只要反應時間超過「過去5分鐘第99百分位」就視為異常。
動態閾值 = 過去 5 分鐘 p95 延遲時間 × 1.5
🔹 優點:可精準反映真實延遲情況,不怕偶發尖峰。
🔹 缺點:需有穩定的監控資料來源。
在資源不足的情況下,是否有其他擴充方案?
使用斷路器只是「緩解」,非「根治」。根本的問題可能在於基礎架構(如自動擴容、快取機制、資料庫優化)。要反思是否依賴了權宜之計而忽略長期穩定性


