← 中文资源

简体中文版本

用令牌桶限流器对 API 限流

实现按固定速率补充的令牌桶,每请求消耗一个令牌,桶空时返回 429 与 Retry-After。

阅读英文原文

突发后稳态

容量 20、每秒补 5 的令牌桶允许客户端突发 20 请求,之后维持每秒 5。桶连续补充,静默期可回充令牌至上限。

class TokenBucket {
  take() {
    const now = Date.now();
    this.tokens = Math.min(this.cap, this.tokens + (now - this.last) / 1000 * this.refill);
    this.last = now;
    if (this.tokens >= 1) { this.tokens -= 1; return true; }
    return false;
  }
}

共享状态

每实例限流会让客户端速率乘以实例数。把桶放入 Redis 并用原子 Lua 脚本,使所有实例执行同一全局限额。

node tools/bucket-store.mjs --redis redis://localhost:6379

预期结果

超容量的突发得到 429 与 Retry-After,持续速率被补令牌速率封顶,负载均衡后两实例执行同一共享限额。遵守 Retry-After 的客户端会退避而非放大突发。桶允许至上限的瞬时突发,不会把瞬时速率压到补令牌值。