题目与范围
本题考察 API 协议边界设计。参考文档是 2026 年 5 月 23 日发布的 Internet-Draft,还不是 RFC;回答要先说明这个状态。部署可能只采用部分字段,因此契约必须能安全降级。
面试官考察什么
- 明确区分配额策略元数据与当前可用配额。
- 结构化字段解析、多时间窗口、配额单位和分区键。
- 与 429、Retry-After、网关、CDN 及缓存陈旧值的关系。
- 暴露限额带来的隐私和拒绝服务风险。
- 客户端把提示视为非绑定信息,能够处理缺失或畸形字段并退避。
推荐答题结构
先定义配额维度和责任归属。展示包含策略与当前限额的响应,再解释客户端如何排队。补充缓存与中间层规则、安全约束、观测指标和带功能开关的渐进发布,以便草案变化时不破坏客户端。
深入拆解:提供有用提示但不承诺容量
分离策略和当前状态
RateLimit-Policy 描述命名配额,例如 "tenant";q=1000;w=60。RateLimit 报告当前可用配额和有效窗口,例如 "tenant";r=420;t=23。策略可包含多个项目和可变窗口。服务端仍是最终权威;这些值是提示,不是租约或服务等级保证。
定义分区和单位语义
说明一个配额单位代表请求、字节、Token 还是加权操作。分区键可区分租户或资源,但不要把邮箱、原始用户 ID 或密钥放入响应头。策略名称应稳定并带版本;不改变名称却改变单位会让客户端节流失效。
协调 429 与 Retry-After
服务端知道拒绝请求何时可再次尝试时返回 Retry-After。两者同时出现时,客户端优先遵守 Retry-After;RateLimit 用于安排后续工作。草案没有规定具体节流算法,所以客户端仍需封顶指数退避、抖动、截止时间和写操作幂等规则。
让缓存和中间层参与契约
缓存响应的 RateLimit 可能陈旧,响应具有正的 current age 时应忽略。不了解配额语义的中间层不能让响应看起来更宽松。强制更严格限额的网关可以传达更严格策略,同时在遥测中区分源站与网关决定。
保护可用性与隐私
不要暴露会泄露流量规模或放大攻击的超大窗口。限制可用配额与窗口的比值,校验结构化字段并忽略畸形值。容量紧张时可以降低广告值,但客户端仍须处理拒绝,因为上一次提示健康并不代表本次一定成功。
示例回答
“我会按租户和操作定义带版本的命名策略,明确单位,并把策略元数据与当前剩余配额分开。该文档还是 Internet-Draft,因此客户端把两类字段都当作可选提示。被拒绝的请求由 Retry-After 指导,RateLimit 安排后续速度。CDN 让陈旧值失效,网关不会把源站限额放宽,分区键不含身份信息。SDK 防御性解析结构化字段,使用抖动和共享队列;先按 SDK 版本灰度并记录宣称限额与实际执行限额。”
常见失误与修正
- 把草案称为 RFC → 记录 Internet-Draft 状态,并用版本化契约隔离。
- 把剩余配额当作许可 → 它只是提示;容量紧张时服务端仍可拒绝。
- 在分区键放用户标识 → 使用不透明、低基数名称并评估隐私暴露。
- 信任缓存响应头 → 忽略陈旧值,由源站执行限额。
- 每次 429 立即重试 → 遵守
Retry-After,加入抖动并按方法定义幂等性。
评分标准与自检
评分点包括策略/状态分离、单位与分区、429 交互、缓存行为、隐私、客户端节流、灰度安全和指标。高质量回答应说明每个字段的含义、不能保证什么,以及字段缺失、陈旧或畸形时客户端如何行动。
追问与延伸
响应含有两个窗口怎么办?
按最先耗尽的约束安排速度,同时保留全部项目用于观测。SDK 不应把单位或分区键不同的窗口悄悄合并。
成功响应应包含 RateLimit 吗?
可以,但客户端不能假定每个响应都有。只有在产品确实需要时发送,并确保缓存不会把旧值变成当前承诺。
如何发布变化中的草案?
协商响应头配置或策略版本,记录解析降级,按 SDK 版本灰度;新字段保持可选,同时稳定 429 与 Retry-After 行为。
哪些指标证明契约有效?
按网关和 SDK 版本记录宣称与执行限额、陈旧值决策、429 率、重试放大、队列延迟、最终成功率及隐私安全的分区基数。