Rate Limiting Your API:算法、实现与背后的战略思考
发布: (2026年3月30日 GMT+8 08:22)
5 分钟阅读
原文: Dev.to
Source: Dev.to
每个您向互联网公开的 API 最终都会被滥用——自动爬虫、凭证填充机器人、行为异常的集成,甚至是循环运行过快的善意客户端。没有速率限制,单个恶意行为者就能耗尽所有服务器资源,导致其他所有用户的体验下降。
Threats Addressed by Rate Limiting
- Resource protection – 防止任何单个客户端消耗不成比例的 CPU、内存、数据库连接或带宽。
- Cost control – 不受约束的客户端可能在几分钟内产生巨额费用(例如 AI 推理 API、短信提供商、支付处理器)。
- Abuse prevention – 凭证填充和枚举攻击依赖于大量请求;速率限制提高了攻击者的成本。
- Fair access – 在多租户系统中,速率限制确保一个租户的流量激增不会降低其他所有人的体验。
常用算法
固定窗口
- 在固定时间间隔内统计每个客户端的请求数。
- 在 Redis 中的实现:使用单个
INCR加EXPIRE。 - 弱点:边界问题——客户端可以在一个窗口的末尾发送最大请求量,然后在下一个窗口的开始再次发送,从而短时间内将速率翻倍。
滑动窗口日志
- 在窗口内跟踪每个请求的时间戳,消除边界问题。
- 缺点:占用内存大(例如,1,000 请求/分钟 × 10,000 客户端 = 1,000 万时间戳)。
- 最适合低流量、高价值的接口,如登录或密码重置。
滑动窗口计数器 (推荐默认)
- 为当前和前一个固定窗口维护计数器,然后根据当前窗口已进行的时间比例计算加权计数。
- 在准确性、内存效率和实现简易性之间取得良好平衡。
令牌桶
- 将速率限制建模为一个以恒定速率填充的桶。
- 两个参数:填充速率(持续吞吐量)和 桶容量(突发容忍度)。
- 被大多数云服务提供商使用,并自然映射到分层计费模型。
分层速率限制
- Edge / Load Balancer (Nginx, Cloudflare, AWS API Gateway) – 在流量到达应用服务器之前保护它们免受过量流量的影响。
- API Gateway or Middleware – 通过已认证用户、API 密钥、订阅层级或端点实施业务层面的限制。
- Individual Services – 在微服务架构中,防止上游服务异常导致下游依赖被压垮。
每一层都缓解不同的故障模式;不要只依赖单一防线。
对客户端的透明度
- 在每个响应中包含速率限制头部:
X-RateLimit-Limit– 允许的最大请求数。X-RateLimit-Remaining– 当前窗口中剩余的请求数。X-RateLimit-Reset– 窗口重置的时间(纪元时间)。
- 在返回
429 Too Many Requests响应时,添加Retry-After头部,指示客户端何时可以重试。 - 这将速率限制从一种粗糙的工具转变为 API 与其使用者之间的协作机制。
实用建议
- 默认算法:Sliding Window Counter – 在保持接近准确的同时,内存开销极小,且不需要完整日志的复杂性。
- 通过 API 密钥识别客户端,而不是通过 IP 地址。由于共享的企业代理和僵尸网络分布式请求,基于 IP 的限制日益不可靠。
- 将速率限制视为 产品决策 同时也是技术决策:定义层级限制,决定何时返回
429与何时进行优雅降级,并根据用户体验预期来确定突发容量大小。
阅读完整文章以获取完整的算法实现、Redis 示例代码以及针对基于订阅的 API 设计速率限制层级的指南。
原始发布于 NovVista。