Varidata 新聞資訊
知識庫 | 問答 | 最新技術 | IDC 行業新聞
Varidata 知識文檔

API 閘道中的速率限制與熔斷指南

發布日期:2026-09-17
API 閘道速率限制與熔斷機制示意圖

速率限制用於控制請求量,熔斷用於阻止對不健康服務的持續呼叫。這兩種模式都能保護你的 API,避免系統崩潰。設想一下秒殺情境:成千上萬的請求會在同一時間打到你的 API 閘道上。沒有任何限制時,伺服器會迅速變慢,直到幾乎停擺。再設想某個下游服務發生故障:所有請求都會堆積在它後面,故障會擴散到整個平台。熔斷器會在損害蔓延之前切斷這個「生病」的服務。你將學習如何在 ngrok、Azure 和 Express.js 中設定速率限制與熔斷機制。這些工具能讓原本脆弱的流量系統從「硬撐到崩」變成「有彈性地承壓而不垮」。

為什麼你的 API 閘道需要保護

流量尖峰與過載

設想一次限時搶購活動。你的團隊在中午發佈一款限量商品。成千上萬的使用者會在同一時刻點擊。你的 API 會立刻遭遇巨大的流量洪峰,伺服器也會馬上開始吃緊。回應時間會從毫秒級飆升到秒級,使用者看到的將是不斷旋轉的載入圖示和錯誤提示。這就是最典型的過載場景。如果沒有保護機制,你的 API 閘道無法放緩這波流量衝擊。每一個新請求都會持續堆積,整個系統會在壓力之下逐步失穩。限流提供了一種簡單而有效的手段:它能限制任意單一用戶端發出的過量請求,讓後端只處理可承受範圍內的流量,而不至於崩潰。過載保護能在需求激增時維持系統穩定。

流量模式可能在幾分鐘內就發生變化。一則爆紅貼文可能讓你的流量在短短數分鐘內翻倍,而你的基礎設施未必能如此迅速地擴容。雲端自動擴展也需要時間來啟動新實例,因此你需要在負載變得危險之前,就在入口處設定控制機制。

級聯故障與不健康依賴

一個變慢的下游服務,就足以拖垮整個系統。設想一個支付微服務開始回應遲緩。每個等待其回傳結果的呼叫都會持續占用執行緒,更多請求會在後面排隊,記憶體逐漸被耗盡。其他依賴支付服務的系統也會隨之變慢,故障像連鎖反應一樣不斷擴散。這種級聯過載會非常迅速地摧毀可用性,幾分鐘內,整個平台就可能變得無法回應。

熔斷器可以阻止這種級聯效應。它會持續監控下游服務的健康狀況。一旦錯誤率超過預設閾值,熔斷機制就會開啟,停止向故障服務繼續發送流量。你的系統會快速回傳降級回應,使用者看到的是一條禮貌且明確的提示,而不是漫長的逾時等待。系統中健康的部分仍然能夠繼續運作。

你的閘道位於整個架構的最前端,所有進站流量都會先經過它。它能在異常模式蔓延之前先一步發現問題。保護 API,既要防範突發流量洪峰,也要防範緩慢惡化的系統退化。將速率限制與熔斷結合起來,才能形成完整的防護體系。

速率限制:控制請求數量

速率限制用於限定用戶端在設定時間視窗內可發起的請求數量。它會為每個用戶端、IP、租戶或路由設定最大請求預算,以保護共享容量並確保公平性。當用戶端超過限制時,閘道會回傳 429 狀態碼。若用戶端在收到 429 後採用指數退避等正確行為,就能避免重試風暴進一步壓垮系統。

速率限制的演算法

四種演算法涵蓋了絕大多數場景。令牌桶允許短時間突發流量,但會限制持續性濫用。漏桶會將流量平滑成穩定的輸出速率。固定時間視窗會在離散區間內統計請求數,因此在視窗邊界可能出現突發。滑動視窗則追蹤一個持續移動的時間範圍,從而避免這一邊界問題。比方說,一個機器人理財平台可以採用滑動視窗策略,為每位使用者設定每 5 秒最多 100 次請求;而對於突發型用戶端,設定為每個 key 每分鐘 120 次請求、並允許 20 的突發容量的令牌桶策略也很合適。

如何在閘道中設定速率限制

對寫入操作應施加更嚴格的限制。建立紀錄的 POST 或 PUT 端點,理應比唯讀的 GET 端點擁有更緊的上限。按路由分別設定的方式,可以在抑制高成本操作被濫用的同時,仍對讀取操作保持相對寬鬆。

Spring Cloud Gateway 使用 YAML 路由定義。你可以透過 RequestRateLimiter 篩選器來設定速率限制:

spring:
  cloud:
    gateway:
      routes:
        - id: orders
          uri: http://orders-service
          predicates:
            - Path=/api/orders/**
          filters:
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 20

Azure Front Door 則透過 WAF 原則實作這項能力。你可以建立一條速率限制規則:將每個來源 IP 限制為每分鐘最多 1,000 個請求,並且只對 URL 中包含 /promo 的請求生效。該規則需要包含比對條件、1 分鐘或 5 分鐘的持續時間,以及 Log 或 Block 動作。速率限制規則不支援 Allow。若要真正執行封鎖,你還必須將原則從 Detection 模式切換為 Prevention 模式。

ngrok 提供了更簡單的設定方式。你可以直接在 ngrok agent 設定或控制台中定義速率限制原則,按 IP 或按端點設定在某個時間視窗內的最大請求數。

按使用者配額則是另一層防護。你可以從請求標頭中讀取 API key 或使用者 ID,然後對每個值分別套用獨立計數器。標準方案可能允許每分鐘 120 次請求,而高階方案可放寬至 1000 次。比如,金融科技的貸款資格評估 API 可以設定為每小時 1000 次呼叫,並按 token 成本計費;一個公開天氣 API 則可以將每個 key 限制為每分鐘 60 次請求。面向 token 的速率限制並非按原始請求數計量,而是按處理的 token 消耗計量,這種方式對 AI 工作負載尤其合適,因為它能讓成本控制更貼近真實資源消耗。

閘道中的熔斷機制

三種狀態與一個簡單比喻

可以把它想像成你家中的電路斷路器。正常時它保持閉合,電流可以通過;電流過大時,它會跳脫斷開;問題修復後,你再手動復位,電路恢復供電。軟體熔斷器也是同樣原理。在閉合狀態下,閘道會讓所有呼叫正常通過;在開啟狀態下,它會停止向故障服務發送任何呼叫,並快速失敗;在半開狀態下,它只放行少量探測請求,用於判斷服務是否恢復。如果探測成功,熔斷器就重新閉合;如果探測失敗,它會再次開啟。

觸發閾值決定熔斷器何時切換狀態。你可以設定為:在短時間區間內達到一定數量的逾時後開啟熔斷器,並保持開啟一段時間。具體數值要根據你的服務等級目標來調整。設定得過低,正常抖動都可能觸發熔斷;設定得過高,則表示使用者已經承受了過多故障痛苦。

如何設定熔斷器

回退端點能讓使用者看到優雅降級後的回應,而不是生硬的錯誤。你應主動為失敗做設計,避免故障擴散。好的回退方案通常具備以下特徵:

  • 向使用者回傳清晰、具體、可執行的資訊,而不是籠統錯誤

  • 採用安全的重試邏輯,包括指數退避、最大重試次數和合適的逾時時間

  • 對關鍵呼叫保證冪等性,避免重試造成重複副作用

  • 實現優雅降級,使使用者旅程中至少一部分功能仍可繼續使用

  • 提供明確的恢復路徑,例如替代服務路由或離線模式

當熔斷器開啟時,你的程式碼可以回傳快取資料,而不是直接失敗:

try:
    return await breaker.call(api_call)
except CircuitOpenError:
    # 回退:提供快取資料
    print("Serving cached data (circuit open)")
    return get_cached_fixtures(league_id)

Azure API Management 在後端資源上提供了 circuitBreaker 屬性。你可以分四步進行設定:

  1. 定義後端資源,包括其 URL 和通訊協定。

  2. 新增一條帶有 failureConditioncircuitBreaker 規則,例如在 10 秒區間內累計 1 次失敗即觸發。

  3. 設定 statusCodeRanges 以捕捉特定失敗,例如 429 回應。

  4. 設定 tripDuration,並啟用 acceptRetryAfter,使熔斷器按照後端 retry-after 標頭中給出的時長保持開啟。

這種方式對 Azure OpenAI 後端尤其有效。429 限流回應會將該後端標記為不健康,在此期間熔斷器保持開啟。熔斷模式能夠阻止級聯故障,並提升服務穩定性與韌性。將故障後端從池中移除,可以避免一個「生病」的依賴把原本健康的流量也拖下水。你應分層部署這些防線:每個請求先經過熔斷器,再進入帶退避的重試邏輯,最後才真正發起 API 呼叫。如果熔斷器已經開啟,就直接跳過呼叫並快速失敗。

在 API 閘道中結合速率限制與熔斷機制

公平性 vs. 健康性

速率限制與熔斷器服務於不同目標。速率限制保障公平性,它會將容量在不同用戶端之間平均分配,避免某個使用者獨占資源。熔斷器則關注健康性,它負責發現下游服務的故障並停止繼續與其通訊。前者透過限流控制需求,後者透過熔斷保護穩定性。兩者結合,才能形成真正具備韌性的架構。你的 API 閘道會在入口先施加速率限制,然後再將呼叫路由到各個後端對應的熔斷器。這種分層方式既能阻止流量過載,也能隔離故障傳播。

例如,可以將每個用戶端的速率限制設定為每分鐘 1000 次呼叫;而當某個下游服務在短時間內出現一定數量異常時,對應熔斷器便會開啟,拒絕所有發往該服務的呼叫。用戶端會立即收到降級回應。兩種模式的狀態都應保存在 Redis 之類的分散式快取中。如此一來,即便系統重新啟動,也能保留熔斷狀態與限流計數器,從而防止復原期間發生重複交易。

適合搭配使用的模式

你的流量原則應對每條路由同時使用這兩種模式。先定義速率限制,再附加帶有回退行為的熔斷器。一個平衡良好的流量原則,會為每條路由設定限流規則,並為每個服務設定熔斷閾值。在部署前,要以真實使用模式測試每項流量原則。也要將相同的流量原則結構套用到多個端點。統一的流量原則可以對讀取操作與寫入操作施加不同保護:對寫入端點,採用嚴格限流並搭配快速開啟的熔斷器;對讀取端點,則可以放寬限流,但依然保留熔斷保護。如此一來,流量原則就成為韌性設計的核心控制點。你定義的每一項流量原則,都同時涵蓋公平性與健康性。一套文件清楚的流量原則,也能幫助團隊在事故發生時更快回應。請為每個流量原則端點設定明確且具體的閾值。

只對冪等操作套用重試。GET 呼叫適合重試;帶冪等鍵的 POST 也適合重試;絕不要重試非冪等寫入操作。採用指數退避,例如先等 1 秒,再等 2 秒,再等 4 秒,最多嘗試三次。熔斷器應放在重試迴圈內部,讓每次重試前都先檢查熔斷器是否處於開啟狀態。如果在重試過程中熔斷器開啟,應立即停止重試並回傳回退結果。.NET 中的 Polly 正好提供了這種模式。你可以設定在出現一定數量異常後開啟熔斷器,並保持開啟一段固定時間,同時記錄每次狀態轉換。

當熔斷器處於開啟狀態時,不要繼續重試。應快速失敗並回傳回退回應。比如在金融系統中,如果驗證服務失效而觸發熔斷器,閘道可以回傳帶有維護提示的清晰錯誤碼。用戶端側的重試邏輯也能提升韌性。將 DNS TTL 從 600 秒降低到 60 秒,曾改善過復原時間。熔斷模式可以阻止級聯故障。這種方式也能讓你把請求負載平衡到健康實例上。

生產環境最佳實務

監控、調校與冪等性

無法度量,就無法調校。先建立監控體系,追蹤每個 IP、token 或路由的請求速率。關注頻寬尖峰,並分析請求模式,以區分機器人流量與真實使用者。大量 404,以及一波波出現的 429 或 503 回應,都是需要調整限流規則的訊號。這些指標能幫助你判斷 API 限流規則是過緊還是過鬆。

一開始應保守設定閾值。可使用基線比較,例如中位數加上兩個標準差,並按週檢視規則。再根據實際流量模式,按小時和工作日進行調整。對於異常偵測,可以最佳化 F1-score,在精確率與召回率之間取得平衡;也可以透過 ROC 曲線分析,選擇距離左上角最遠的閾值點,以在提高真正率的同時盡量降低誤報率。

冪等鍵能讓 POST 和 PUT 端點的重試變得安全。當用戶端送出兩次相同的 key 時,系統只會處理一次請求,這能避免復原過程中的重複交易。熔斷狀態與限流計數器都應儲存在 Redis 這類共享快取中,以確保多實例與重新啟動後的狀態一致性。

避免常見陷阱

過於嚴格的限制會造成真實損害。閾值過低會誤傷合法使用者,損害轉換率;閾值過高又起不到任何過載保護作用。正常的業務流量高峰,例如電商秒殺,可能會被誤判為攻擊並遭到封鎖;而能模擬正常行為的攻擊者,則可能繞過防護,形成安全漏洞。

缺少回退機制,會讓使用者只能面對生硬的原始錯誤。熔斷器開啟時,務必始終定義好回退回應。忽視半開狀態也是常見陷阱。半開狀態存在的意義,就是用少量請求探測服務是否恢復;如果跳過這個階段,熔斷器就可能永遠無法再次關閉。複雜的速率限制機制本身也會消耗系統資源。設計不佳的限流方案,甚至可能增加系統負擔,而不是減輕壓力。請在測試環境中驗證每一種限流策略,再投入生產。這樣,你才能在沒有意外的情況下,將請求負載平衡到健康實例。

速率限制與熔斷以不同方式保護你的系統。前者守護公平性與容量,限制每個用戶端可發送的請求數量;後者守護健康性與復原能力,在故障擴散前切斷對失敗服務的呼叫。兩者結合,便能同時涵蓋需求側壓力與穩定性風險。先從保守閾值開始,觀察監控資料,再根據真實流量模式逐步調整。你的閘道位於系統最前端,因此請從今天起就在這裡設定好這兩種模式。為每一條關鍵路由都加上限流規則與熔斷器。現在多做一點設定,明天就可能少一次停機。

常見問題

速率限制和熔斷有什麼區別?

速率限制用於限制用戶端在某個時間視窗內可發送的請求數量;熔斷則用於停止對故障服務的呼叫。前者保護公平性與容量,後者保護健康性與復原能力。你的閘道需要兩者配合,才能同時應對流量尖峰與服務故障。

我該選擇哪種速率限制演算法?

令牌桶允許短時突發,同時限制持續濫用;漏桶將流量平滑成穩定輸出;固定視窗在離散時間區塊內計數;滑動視窗追蹤移動時間範圍,可避免邊界突發。具體應根據你的流量形態以及你對突發流量的容忍度來選擇。

熔斷器如何決定何時開啟?

你需要設定觸發閾值,例如在短時間內發生一定數量的逾時。一旦故障超過這條線,熔斷器就會開啟,並保持開啟一段時間。之後它會進入半開狀態,用少量請求測試服務是否恢復。

熔斷器開啟時會發生什麼?

你的閘道會停止向故障服務發送所有呼叫,並快速失敗。它會回傳回退回應,而不是原始錯誤。你可以提供快取資料,或顯示明確的維護提示。這樣系統中健康的部分仍能繼續運作。

速率限制計數器和熔斷狀態應該儲存在哪裡?

應將兩者都儲存在 Redis 這類共享快取中。這樣可確保多個閘道實例以及系統重新啟動後的計數器與熔斷狀態一致。如果沒有共享狀態,每個節點都會各自追蹤自己的限額,用戶端就可能突破你原本設定的總上限。

您的免費試用從這裡開始!
聯繫我們的團隊申請實體主機服務!
註冊成為會員,尊享專屬禮遇!
您的免費試用從這裡開始!
聯繫我們的團隊申請實體主機服務!
註冊成為會員,尊享專屬禮遇!
Telegram Teams