限流算法是什么
限流算法决定单位时间内放行多少请求。固定窗口实现最简单,但窗口边界处可能放行约两倍流量;滑动窗口统计更平滑,内存开销略高;令牌桶按速率补充令牌,允许突发;漏桶以恒定速率流出,擅长削峰填谷。选择取决于要抑制突发还是允许突发。
放在哪一层
限流要放在能全局计数的位置,否则按实例限流会在扩容后把整体阈值放大到实例数倍,扩容反而成了放大故障的手段。常见组合是网关做粗粒度全局限流,服务内做单实例自我保护,并在拒绝时返回明确的重试等待时间,让客户端能配合退避。
四种算法
| 算法 | 特点 | 适用场景 |
|---|---|---|
| 固定窗口 | 实现简单,窗口边界可放行约两倍流量 | 粗粒度保护 |
| 滑动窗口 | 统计平滑,内存开销略高 | 需要精确限流的接口 |
| 令牌桶 | 按速率补令牌,允许突发 | API 配额与短时突发 |
| 漏桶 | 恒定速率流出,削峰 | 保护下游处理速率 |
基本信息
| 限流维度 | 按用户、租户、接口或来源地址 |
|---|---|
| 拒绝语义 | 返回明确的状态码与重试等待时间 |
| 全局与本地 | 网关全局限流加服务本地保护 |
| 动态阈值 | 随容量与下游健康度调整 |
典型使用场景
- 开放 API 配额:按调用方限制单位时间请求量
- 秒杀入口削峰:入口拦住超额流量,保护下游
- 保护数据库:限制写入速率,避免连接数被打满
- 租户隔离:防止单个租户占满共享资源
- 防爬与防刷:按来源地址限制异常高频访问
阈值怎么定
阈值不能照搬压测的极限值,要留出安全余量,因为线上还叠加了重试流量、监控采集与批处理任务。常用做法是取单实例实测容量的一定比例作为保护线,再按下游最慢环节的承受能力确定全局限额。阈值还需要随实例规格与下游容量变化定期复核,扩容后忘记调整会让限流形同虚设。
限流要定义拒绝语义:返回明确状态码并携带重试等待时间,比静默排队或直接超时更有利于客户端配合与问题定位。