← 中文资源

简体中文版本

限流

限流控制客户端在时间窗口内的请求数量,保护共享容量并维护公平使用,同时返回明确的拒绝信号。

阅读英文原文

算法与权衡

固定窗口简单,但允许在窗口边界突发。滑动窗口记录时间戳并统计最近区间,更准确但占内存。令牌桶按固定速率补充令牌并允许配置突发。漏桶以恒定速率出队,平滑输出而不是接纳突发。

class TokenBucket {
  constructor(capacity, refillPerSecond) {
    this.capacity = capacity;
    this.tokens = capacity;
    this.refillPerSecond = refillPerSecond;
    this.updatedAt = Date.now();
  }

  take(count = 1) {
    const now = Date.now();
    const elapsed = (now - this.updatedAt) / 1000;
    this.tokens = Math.min(this.capacity, this.tokens + elapsed * this.refillPerSecond);
    this.updatedAt = now;
    if (this.tokens < count) return false;
    this.tokens -= count;
    return true;
  }
}

定义契约

记录键(IP、API Key、用户)、限制、窗口、突发大小和失败响应。超限时返回 429 Too Many Requests 与 Retry-After,并在可用时返回限流头。被拒绝的请求应尽量便宜:在认证或数据库等昂贵工作之前,在边缘执行。

何时使用

对公共 API、登录、密码重置、搜索和昂贵计算使用限流。与防抖/节流相比,限流是服务端准入策略;与重试预算相比,它限制所有流量,而不仅是重试。

陷阱

分布式执行需要共享计数器或近似方案;按实例限制会乘以实例数。按 IP 限流对 NAT 和共享办公网络不公平。过严的限制阻断合法突发,过松的限制没有保护作用。应测量拒绝率和延迟,并随流量模式变化审查限制。

相关资源