用途
Rate Limiting Patterns 用于保护 API 免受滥用,提供基于 Redis 的分布式限流实现与算法选型参考。典型使用场景包括:保护公开 API、实现分层限流(免费/专业/企业)、在多个实例间扩展限流、防止认证端点被暴力破解、管理第三方 API 消耗量。
主要能力
算法选型
| 算法 | 使用场景 | 突发处理 |
|---|---|---|
| 令牌桶(Token Bucket) | 通用 API,允许突发 | 优秀 |
| 滑动窗口(Sliding Window) | 精确,无突发尖峰 | 良好 |
| 漏桶(Leaky Bucket) | 恒定速率,排队多余请求 | 无 |
| 固定窗口(Fixed Window) | 简单,存在边界问题 | 中等 |
SlowAPI + Redis(FastAPI)
基础配置使用 Limiter,指定 key_func、storage_uri="redis://localhost:6379",策略为 moving-window,并通过 SlowAPIMiddleware 挂载到应用。
端点限流
通过装饰器为不同端点设置限制:认证登录 10/minute(严格)、读取 100/minute(常规)、写入 20/minute(中等)。
基于用户的限流
get_user_identifier 在已认证时按用户 ID 限流,否则按 IP。
自定义令牌桶(Redis)
TokenBucketLimiter 接受 Redis 客户端、容量(capacity)与补充速率(refill_rate,每秒令牌数),通过 Lua 脚本原子性地检查并消费令牌,设置过期时间 3600 秒。
滑动窗口计数器
SlidingWindowLimiter 使用 Redis 有序集合,先移除旧条目(zremrangebyscore),统计当前窗口(zcard),添加当前请求(zadd),并设置窗口两倍的过期时间;返回是否允许与剩余额度。
分层限流
通过 UserTier 枚举与 TIER_LIMITS 字典定义免费(100/小时)、专业(1000/小时)、企业(10000/小时)配额,并用 get_rate_limit 动态生成限流字符串。
响应头(RFC 6585)
返回 X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset 与 Retry-After 响应头。
429 错误响应
rate_limit_exceeded_handler 返回 429 状态码,内容包含问题类型、标题、状态、详情、实例 URL,并附带 Retry-After 与限流响应头。
使用方式
- 存储选择 Redis(分布式、原子操作)。
- 大多数 API 推荐使用令牌桶算法。
- 限流键:已认证时用用户 ID,否则用 IP + 指纹。
- 认证端点:10/分钟(严格)。
- 读端点:100–1000/分钟(视层级而定)。
- 写端点:20–100/分钟(中等)。
限制与注意事项
应避免的反模式:
- 禁止在分布式系统中使用内存计数器(重启丢失、不跨实例共享)。
- 禁止跳过内部 API 的限流(纵深防御)。
- 禁止在不考虑边界尖峰的情况下使用固定窗口(用户可能在 0:59 命中 100 次、1:01 命中 100 次,即 2 秒内 200 次)。
相关技能
auth-patterns(认证集成)、resilience-patterns(断路器)、observability-monitoring(限流指标)。
能力细节
- token-bucket:关键词 token bucket、rate limit、burst、capacity;解决如何实现令牌桶限流、在限速的同时允许突发。
- sliding-window:关键词 sliding window、moving window、rate limit;解决如何实现精确限流、避免固定窗口边界问题。
- slowapi-redis:关键词 slowapi、fastapi rate limit、redis limiter;解决如何为 FastAPI 添加限流、分布式限流。
- tiered-limits:关键词 tiered、user tier、free pro enterprise;解决不同订阅层级的差异化限流、基于用户的限流。