Skip to content

Latest commit

 

History

History
50 lines (35 loc) · 3 KB

File metadata and controls

50 lines (35 loc) · 3 KB

rate limiter – smudge.ai blog

TL;DR

速率限制用于防止服务过载,确保公平性与稳定性。主要算法包括:固定窗口法(简单但允许突发流量)、滑动窗口法(平滑流量但资源消耗高)、令牌桶算法(支持突发且控制长期平均速率)。实现时需使用持久化存储(如Redis)、设计容错机制(链路失败启用开放策略)、选择用户标识(IP/设备指纹等),并返回429状态码及剩余配额。建议根据场景选择:简单场景用固定窗口,高并发场景选滑动窗口近似算法,需平衡突发与长期流量则用令牌桶。

Summary

文章总结:

速率限制的必要性
防止服务过载(如聊天中的垃圾消息、暴力破解攻击、API资源垄断),通过限制单位时间内请求量,确保公平性与稳定性。


三种核心算法

  1. 固定窗口法(Fixed Window)

    • 机制:预设时间窗口内允许固定请求数,窗口结束时重置计数器。
    • 优点:简单易实现,窗口起始时间固定(如GitHub每小时限5000次API调用)。
    • 缺点:允许窗口结束前的突发请求(达2倍限额)。时区处理复杂(需同步用户时区,但可能导致滥用)。
    • 改进:窗口起始时间与用户首请求绑定,但需显示剩余等待时间。
  2. 滑动窗口法(Sliding Window)

    • 机制:按时间比例动态计算窗口内请求数,避免突发流量。
    • 优点:流量平滑,适合高并发场景(如Cloudflare的近似算法)。
    • 缺点:需存储所有请求时间戳,资源消耗高。实际使用近似算法(如“浮动窗口”加权计算历史和当前窗口)。
  3. 令牌桶(Token Bucket)

    • 机制:桶内按固定速率填充令牌,每请求消耗1令牌,无令牌时阻断。
    • 优点:支持突发流量,区分瞬时峰值与长期速率(如Twitch聊天每4秒补1令牌,限1消息/4秒)。
    • 应用案例:Stripe每秒补2000令牌(500容量桶,限100/s长期平均);OpenAI每日补200令牌。

关键注意事项

  • 数据存储:使用持久化存储(如Redis)而非内存,应对横向扩展或服务重启。
  • 容错设计:链路失败时“启用开放”(允许所有请求,避免完全阻断)。
  • 键选择:按用户ID/API Key/IP等唯一标识限流。未认证用户可通过IP或设备指纹。
  • 错误反馈:返回429状态码,提供剩余配额等元数据(如GitHub和OpenAI的响应头)。

算法选择建议

  1. 固定窗口:适合简单场景或需严格起始时间(如日历日限流)。
  2. 滑动窗口近似算法:高流量场景的平滑控制(如Cloudflare实现)。
  3. 令牌桶:需支持突发流量同时控制长期平均速率(如聊天应用或API限流)。