结论:四种经典算法:1)固定窗口——实现最简,窗口边界处可承受两倍速率突刺;2)滑动日志/滑动窗口——精确但存储开销大,常用滑动窗口计数近似;3)漏桶——恒定速率出队,强行整形流量(适合下游保护);4)令牌桶——按速率放令牌、允许攒桶突发,是通用首选(Nginx limit_req、Guava RateLimiter)。分布式限流的本质是把计数状态集中到共享存储(Redis + Lua 原子执行)或接受近似(本地限流 × 节点数)。
展开:分布式实现要点:Redis 方案用 Lua 脚本把"读令牌数、按时间差补充、扣减、写回"做成原子操作,key 按 用户/租户/IP 维度;时钟用 Redis 服务端时间避免节点时钟漂移。精度与成本的权衡:强一致限流(每请求一次 Redis 往返)在超高 QPS 下自身成为瓶颈,工程上常用"本地令牌桶 + 周期性向 Redis 同步配额"或 Envoy 的限流服务(RLS)分级:边缘粗限(IP 级)+ 应用精限(账号级)。设计维度:限流对象(IP 易伪造要配合身份)、超限响应(429 + Retry-After)、突发策略(API 网关的 burst 参数)、降级(限流器故障时 fail-open 还是 fail-close,安全接口选 close)。易错点:1)用单节点计数器限全局导致横向扩容后限额翻 N 倍;2)登录/短信接口按 IP 限,NAT 后企业用户集体被误伤——要多维度组合。
-- Redis 令牌桶核心:原子补充+扣减
local tokens = math.min(cap, tonumber(redis.call('GET', k) or cap) + rate * elapsed)
if tokens >= 1 then redis.call('SET', k, tokens - 1, 'EX', ttl) return 1 end
return 0
追问方向:GCRA(信元速率算法,Redis Cell/Envoy 采用)与令牌桶的等价性、限流与熔断在容量保护上的分工。