Skip to content

概念卡片:限流算法

一句话机制:限流是「有损服务」的保护手段——超过阈值就拒绝/排队/降级,避免瞬时流量打垮系统;核心是三种算法:滑动窗口(时间窗口内计数)、漏桶(固定速率流出,平滑流量)、令牌桶(固定速率放令牌,允许突发)。

三种限流算法

算法原理特点适用
计数器单位时间窗口内计数粗糙,窗口边界会突刺最简单场景
滑动窗口窗口随时间滑动,精确统计窗口内请求平滑计数Sentinel 采用
漏桶固定速率流出,桶满溢出(拦截或丢弃)平滑突发流量,不能突发流量整形
令牌桶固定速率放令牌,请求需取令牌,桶满令牌丢弃允许突发(令牌可积累)主流(Guava RateLimiter)

关键代码示例(Guava 令牌桶)

java
RateLimiter rateLimiter = RateLimiter.create(10);  // 每秒 10 个令牌(QPS)

if (rateLimiter.tryAcquire()) {   // 尝试取一个令牌
    System.out.println("允许通过");
} else {
    System.out.println("被限流了");
}

令牌桶的两个关键参数

参数含义
rate生成令牌速度(如 rate=2 → 每秒 2 个令牌)
burst桶容量(如 burst=10 → 最多积累 10 个令牌,支持突发)

限流的常见维度

  • 限制总并发数(数据库连接池、线程池)
  • 限制瞬时并发数(nginx limit_conn
  • 限制时间窗口平均速率(nginx limit_req、Guava RateLimiter)
  • 限制远程接口调用速率、MQ 消费速率

不变量(必须成立的约束)

  • 限流是有损的(被限流的用户会不开心),但比「全部不可用」好。
  • 漏桶不能突发(恒定速率),令牌桶能突发(令牌可积累),高并发秒杀场景优先令牌桶。
  • 限流要评估好阈值,乱用会误伤正常流量、影响体验。

踩坑案例

  • 现象:秒杀瞬间流量打满,用漏桶限流,导致正常用户也被排队。 原因:漏桶恒定速率,无法应对「允许短时突发」的诉求。解决:改用令牌桶(积累的令牌吸收突发),或令牌桶 + 漏桶组合。

常见误解

  • 以为限流能保证系统永不挂 → 限流是「有损保护」,只是把「全挂」变成「部分拒绝」。
  • 以为漏桶和令牌桶一样 → 漏桶平滑但不能突发,令牌桶允许突发,场景不同。

关联

最近更新