rate limiting参数配置与中间件缓存同步 - 第1节
1.1 什么是限流
限流(Rate Limiting)是一种控制资源访问频率或并发量的技术手段。它通过限制在特定时间窗口内允许通过的请求数量,防止系统被突发流量冲垮,确保后端服务的稳定性和公平性。
限流的核心目标可以概括为三点:
- 保护系统资源:防止数据库、CPU、内存等资源被过度消耗。
- 保障服务质量:避免因个别用户过度占用资源而影响其他用户的正常使用。
- 成本控制:在云服务或按量计费场景下,限制不必要的资源开销。
关键认知:限流不是拒绝用户,而是有策略地延迟或降级请求,让系统在过载时仍能提供可预期的服务。
1.2 为什么需要限流
在分布式系统和微服务架构中,限流是保障系统韧性的第一道防线。以下场景如果没有限流,系统极易发生雪崩:
| 场景 | 风险描述 | 限流效果 |
|---|---|---|
| 突发流量(秒杀、热点事件) | 瞬间请求量达到正常值的 10~100 倍,服务直接 OOM 或连接池耗尽 | 平滑流量峰值,保证核心交易链路可用 |
| 恶意爬虫 / DDoS 攻击 | 大量无效请求占用带宽和计算资源,正常用户无法访问 | 快速识别并拦截异常高频请求 |
| 上游服务故障重试风暴 | 客户端重试 + 负载均衡重试导致请求量指数级放大 | 限制重试频率,防止级联故障 |
| 资源瓶颈(数据库连接、API 配额) | 超过数据库最大连接数或第三方 API 调用配额 | 提前拒绝请求,避免超时和报错 |
常见误区:限流不能替代容量规划。限流是“兜底”手段,合理的容量评估和弹性伸缩才是根本。
1.3 常见限流算法简介
不同的限流算法在精度、内存开销和突发处理能力上各有优劣。下面介绍三种最核心的算法:令牌桶、漏桶和滑动窗口。
1.3.1 令牌桶算法(Token Bucket)
令牌桶以固定速率向桶中放入令牌,每个请求需要消耗一个令牌才能被处理。桶有容量上限,允许一定程度的突发流量。
- 核心参数:
rate(令牌生成速率)、capacity(桶容量) - 优点:允许突发,实现简单,性能高
- 缺点:短期突发可能超过实际处理能力
- 典型应用:Guava RateLimiter、Nginx ngx_http_limit_req_module
1.3.2 漏桶算法(Leaky Bucket)
漏桶将请求放入一个固定容量的桶中,然后以恒定速率从桶底“漏出”请求进行处理。桶满时新请求被丢弃。
- 核心参数:
leak_rate(漏出速率)、bucket_size(桶容量) - 优点:输出流量绝对平滑,适合流量整形
- 缺点:无法应对突发流量,所有请求必须排队等待
- 典型应用:网络 QoS、流量整形设备
1.3.3 滑动窗口算法(Sliding Window)
滑动窗口将时间划分为多个小格子,维护一个固定大小的窗口,统计窗口内所有格子的请求总数。窗口随时间向前滑动,丢弃过期格子数据。
- 核心参数:
window_size(窗口大小,如 1s)、threshold(阈值) - 优点:相比固定窗口,能有效避免“临界突变”问题,精度可控
- 缺点:需要存储窗口内每个格子的计数,内存开销略高
- 典型应用:Redis 限流、API Gateway 限流
1.4 三种算法对比
| 特性 | 令牌桶 | 漏桶 | 滑动窗口 |
|---|---|---|---|
| 突发处理 | 允许突发(桶容量内) | 不允许突发 | 允许突发(窗口内) |
| 输出流量 | 可能不平滑 | 绝对平滑 | 取决于窗口粒度 |
| 内存开销 | 低(仅维护计数器) | 低(仅维护队列长度) | 中(需存储格子计数) |
| 精度 | 较高 | 高 | 高(格子越细精度越高) |
| 实现复杂度 | 简单 | 简单 | 中等 |
| 典型场景 | API 限流、微服务限流 | 流量整形、网络 QoS | 分布式限流、网关限流 |
选型建议:
• 需要允许突发流量且实现简单 → 令牌桶
• 需要绝对平滑的输出流量 → 漏桶
• 需要高精度且能接受一定内存开销 → 滑动窗口
• 实际生产环境中,令牌桶和滑动窗口的组合使用非常常见。
• 需要允许突发流量且实现简单 → 令牌桶
• 需要绝对平滑的输出流量 → 漏桶
• 需要高精度且能接受一定内存开销 → 滑动窗口
• 实际生产环境中,令牌桶和滑动窗口的组合使用非常常见。