代表性面试主题

后端面试:如何设计可执行的 429 与 Retry-After 契约?

后端中等
OfferCC 编辑团队发布 更新

题干

一个公共 API 在按租户、账号和端点执行限流。客户端收到 429 后经常立即重试,导致恢复更慢;不同 SDK 对 Retry-After 的理解也不一致。请设计服务端响应契约和客户端处理策略,说明何时可重试、如何计算等待时间、怎样避免重试风暴,并给出验证指标。

题干与适用场景

这道题考察限流的协议边界,而不是只说“加一个 Redis 计数器”。RFC 6585 定义 429 表示在一段时间内请求过多,服务端可以用 Retry-After 提示等待时间;RFC 9110 还规定了秒数和 HTTP 日期两种表示。你需要把这些语义转成客户端可执行的行为。

适用于公共 API、第三方集成、批处理 SDK 和多租户平台。回答要区分限流、服务过载、认证失败和业务冲突,避免让客户端对所有 4xx 或 5xx 盲目重试。

面试官真正想听什么

  • 限流键、窗口、配额和响应头是否能解释“谁被限制、何时恢复”。
  • 429 的 body、Retry-After、请求 ID 和剩余配额信息是否一致且不泄露租户数据。
  • 客户端如何解析秒数或日期、加入抖动、尊重截止时间并限制尝试次数。
  • 非幂等写入、异步任务和网络超时的重试边界是否清楚。
  • 如何监控限流命中、恢复时间、重试放大和成功率,验证契约真的降低风暴。

推荐回答结构

先定义限流维度和错误分类,再给出 429 响应示例及 Retry-After 计算规则。客户端按响应头、请求类型和本地预算决定等待、放弃或转为异步;所有重试使用指数退避和随机抖动,不能绕过服务端给出的更长等待。

最后说明网关、应用、SDK 和业务操作的责任边界,以及如何用故障注入和多客户端压测验证。

深入拆解:从响应到重试

让限制原因可解释

服务端按租户、凭证、IP、端点或全局资源定义键,并在 429 中返回稳定错误类型、请求 ID 和安全的限流原因。若多个限流器同时触发,Retry-After 取需要等待的最长时间;不要返回可被用来枚举其他租户配额的细节。

正确生成 Retry-After

秒数表示至少等待多少秒,HTTP 日期表示恢复时间点。服务端使用单调时间计算内部窗口,再把结果转换为协议值,向上取整并设置上限。代理或时钟偏差可能让日期过期,客户端仍需加入最小等待和抖动。

客户端解析和退避

优先尊重 Retry-After;缺失或非法时使用带上限的指数退避。每个逻辑请求维护尝试预算和总截止时间,多个并发任务共享令牌或队列,避免同时唤醒。429 不应无限重试,也不应把同一请求复制到更多连接。

处理幂等边界

GET、HEAD 和明确幂等的 PUT、DELETE 通常可安全重试;POST 只有在幂等键和服务端语义保证下才可重试。若请求可能已在服务端执行而响应丢失,客户端应查询状态或复用相同幂等键,而不是创建新副作用。

观测恢复而非只看错误率

记录限流维度、429 数量、Retry-After 分布、客户端等待、重试放大系数、最终成功率和放弃率。按 SDK 版本和租户分组,区分服务端拒绝、客户端立即重撞与合法流量增长,才能判断契约是否有效。

可直接套用的回答示例

“我会把 429 限制在明确的租户、凭证和端点键上,响应返回稳定错误类型、请求 ID、安全的原因和 Retry-After。服务端用单调窗口计算等待秒数,向上取整并限制最大值;日期格式只作为兼容形式。SDK 优先解析 Retry-After,缺失时使用带抖动的指数退避,每个逻辑请求有总截止时间和最大尝试次数。GET 可重试,POST 只有携带幂等键或先查询状态才重试。监控 429、等待分布、重试放大、最终成功和放弃,并用多客户端同时触发限流验证恢复是否平滑。”

常见失分点与修正

  • 所有失败都重试 → 按状态码、方法语义和错误类型分类。
  • 忽略 Retry-After 格式 → 同时支持秒数和 HTTP 日期,处理非法值。
  • 每个线程独立立即重试 → 共享预算、队列和随机抖动。
  • 把 POST 当天然幂等 → 使用幂等键、查询状态或明确不可重试。
  • 只监控 429 数量 → 观察等待、放大、最终成功和放弃。

评分标准与自检清单

高分回答包含清晰限流键、429 语义、Retry-After 生成与解析、指数退避抖动、总截止时间、幂等边界、并发协调、配额信息安全、网关与 SDK 分工和验证指标。

自检:客户端知道何时恢复吗?时钟不准怎么办?缺 header 怎么办?重试会不会重复副作用?多个任务如何错开?怎样证明恢复更快而非只是错误变少?

追问与延伸

Retry-After 应该返回秒数还是日期?

两种形式都属于 HTTP 语义。秒数更适合短窗口和避免时钟差,日期适合表达明确恢复时间;服务端应稳定使用一种并让 SDK 兼容另一种,客户端校正过期或负值。

网关和应用都限流,返回哪个等待时间?

对客户端可见的最小恢复时间应覆盖所有已知限制,通常取最长等待并保留请求 ID。内部日志记录每层命中,避免只把网关拒绝误归因于业务端。

没有 Retry-After 时能否重试?

只有在方法和错误语义允许、仍有总截止时间且本地退避预算充足时才可重试。使用指数退避、抖动和上限;对不可重试的写入应返回可查询状态或明确失败。

如何测试重试风暴?

让大量不同客户端在同一时刻触发 429,注入非法 header、时钟偏差、连接超时和恢复抖动,观察请求到达曲线、放大系数、恢复时间和最终成功率。

公开来源

同类题目

资源

产品对比

每份对比均基于官方资料,并标注复核日期。

查看完整对比