具代表性的面試主題

後端面試:如何設計可執行的 429 與 Retry-After 契約?

後端中等
OfferCC 編輯團隊發佈 更新

題幹

公共 API 按租戶、帳號和端點限流。客戶端收到 429 後常立即重試,導致恢復更慢;不同 SDK 對 Retry-After 的理解也不一致。請設計服務端回應契約與客戶端策略,說明何時可重試、如何計算等待、怎樣避免重試風暴,並給出驗證指標。

題幹與適用場景

這題考察限流的協議邊界,不是只加 Redis 計數器。RFC 6585 定義 429 表示一段時間內請求過多,服務端可用 Retry-After 提示等待;RFC 9110 規定秒數與 HTTP 日期兩種表示。要把語意轉成客戶端行為。

面試官真正想聽什麼

  • 限流鍵、窗口、配額和回應標頭能解釋誰被限、何時恢復。
  • 429 body、Retry-After、請求 ID 和剩餘配額資訊一致且不洩漏租戶資料。
  • 客戶端解析秒數或日期、加入抖動、遵守截止時間並限制嘗試次數。
  • 非冪等寫入、非同步任務和網路逾時的重試邊界清楚。

推薦回答結構

先定義限流維度和錯誤分類,再給出 429 回應及 Retry-After 規則。客戶端依標頭、請求類型和預算等待、放棄或轉為非同步;所有重試使用指數退避與隨機抖動。

深入拆解:從回應到重試

讓限制原因可解釋

服務端按租戶、憑證、IP、端點或全域資源定義鍵,429 返回穩定錯誤類型、請求 ID 和安全原因。多個限流器同時觸發時取最長等待,不暴露其他租戶配額。

正確產生 Retry-After

秒數表示至少等待多久,HTTP 日期表示恢復時間點。內部用單調時間計算窗口,向上取整並設上限;日期可能受時鐘偏差影響,客戶端仍需最小等待與抖動。

客戶端解析與退避

優先遵守 Retry-After;缺少或非法時使用有上限的指數退避。每個邏輯請求維護嘗試預算和總截止時間,多個任務共享佇列,避免同時喚醒。

處理冪等邊界

GET、HEAD 和明確冪等的 PUT、DELETE 通常可重試;POST 只有帶冪等鍵或服務端保證才可重試。若回應遺失,先查詢狀態或重用相同鍵,不能建立新副作用。

觀測恢復而非只看錯誤率

記錄限流維度、429 數量、Retry-After 分布、等待、重試放大、最終成功與放棄。按 SDK 版本和租戶分組,區分立即重撞與流量增長。

可直接套用的回答示例

「我會按租戶、憑證和端點鍵限流,429 返回穩定錯誤類型、請求 ID、安全原因和 Retry-After。服務端用單調窗口算等待秒數,向上取整並限制最大值。SDK 優先解析 Retry-After,缺少時用帶抖動的指數退避,每個邏輯請求有截止時間和最大嘗試。GET 可重試,POST 需冪等鍵或先查狀態。監控 429、等待、重試放大、最終成功與放棄,並用多客戶端壓測驗證恢復是否平滑。」

常見失分點與修正

  • 所有失敗都重試 → 按狀態碼、方法語意和錯誤類型分類。
  • 忽略 Retry-After 格式 → 支援秒數和 HTTP 日期,處理非法值。
  • 每執行緒立即重試 → 共用預算、佇列和隨機抖動。
  • 把 POST 當天然冪等 → 使用冪等鍵、查詢狀態或明確不可重試。

評分標準與自檢清單

高分回答包含限流鍵、429 語意、Retry-After 產生與解析、退避抖動、總截止、冪等邊界、並發協調、配額安全、分工和驗證指標。

追問與延伸

Retry-After 應返回秒數還是日期?

兩種都符合 HTTP 語意。秒數適合短窗口並避免時鐘差,日期適合明確恢復時間;服務端穩定使用一種,SDK 相容另一種並處理過期值。

閘道和應用都限流,返回哪個等待?

對客戶端可見的等待應覆蓋所有已知限制,通常取最長等待並保留請求 ID。內部記錄每層命中,避免錯誤歸因。

沒有 Retry-After 時能否重試?

只有方法與錯誤語意允許、仍有截止時間和退避預算時才重試。不可重試寫入應返回可查詢狀態或明確失敗。

如何測試重試風暴?

讓大量客戶端同時觸發 429,注入非法標頭、時鐘偏差、連線逾時和恢復抖動,觀察到達曲線、放大系數、恢復時間與成功率。

公開來源

同類題目

資源

產品比較

每份比較均依官方資料整理,並標示複核日期。

查看完整比較