2. 限流基础概念:令牌桶、漏桶、计数器算法的原理与对比
在模型发布场景中,API 网关或推理服务必须应对突发流量、恶意爬虫以及后端资源瓶颈。限流(Rate Limiting)是保护系统不被瞬时洪峰冲垮的第一道防线。本章深入剖析三种最经典的限流算法——令牌桶、漏桶和计数器,从原理、实现到适用场景进行系统对比。
2.1 令牌桶算法(Token Bucket)
令牌桶是目前工业界应用最广泛的限流算法,也是 API Gateway 和 模型推理服务 的首选方案。其核心思想是:系统以恒定速率向桶中放入令牌,每个请求必须获取一个令牌才能被处理;桶有容量上限,允许一定程度的突发流量。
关键参数:
- r(rate):令牌生成速率,即平均每秒放入桶中的令牌数。
- b(burst):桶的最大容量,即允许的瞬时突发请求数。
- 当桶满时,新生成的令牌被丢弃;当桶空时,请求被拒绝或排队等待。
模型发布场景建议: 令牌桶算法非常适合处理 LLM 推理服务的突发请求。例如,设置 r=10(每秒 10 个请求)、b=20(允许瞬间 20 个并发),既能保证长期平均速率,又能容忍用户短时间内的密集调用。
2.2 漏桶算法(Leaky Bucket)
漏桶算法与令牌桶相反,它强制请求以恒定速率流出,无论流入速率多快。漏桶像一个底部有漏洞的水桶,水(请求)以固定速率漏出,桶满则溢出(拒绝请求)。
注意: 漏桶算法严格平滑流量,不允许任何突发。对于模型推理服务,如果用户突然发送一批请求,漏桶会强制排队以恒定速率处理,可能导致高延迟。因此漏桶更适合流量整形场景,而非需要容忍突发的模型 API。
2.3 计数器算法(Counter / Fixed Window)
计数器算法是最直观的限流方式:在固定时间窗口(如 1 秒、1 分钟)内统计请求总数,超过阈值则拒绝后续请求。窗口结束后计数器重置。
常见实现方式:
- 固定窗口计数器: 每个窗口独立计数,窗口切换时瞬间重置。
- 滑动窗口计数器: 将窗口细分为多个小格,滑动统计,精度更高。
# 固定窗口计数器示例(Python)
import time
class FixedWindowCounter:
def __init__(self, limit: int, window_sec: int = 1):
self.limit = limit
self.window_sec = window_sec
self.counter = 0
self.window_start = time.time()
def allow(self) -> bool:
now = time.time()
if now - self.window_start >= self.window_sec:
# 新窗口,重置
self.window_start = now
self.counter = 0
if self.counter < self.limit:
self.counter += 1
return True
return False
固定窗口的临界问题: 假设限制 100 次/秒。如果在第 0.9 秒时累计 100 次,第 1.0 秒窗口重置,第 1.1 秒又累计 100 次。实际上 0.2 秒内通过了 200 次请求,形成流量毛刺。滑动窗口算法通过细粒度分格缓解此问题,但无法完全消除。
2.4 三种算法对比
| 维度 | 令牌桶 | 漏桶 | 计数器(固定窗口) |
|---|---|---|---|
| 核心机制 | 恒定速率放令牌,请求取令牌 | 请求入桶,恒定速率漏出 | 固定窗口内计数,超限拒绝 |
| 突发处理 | 允许突发(桶容量内) | 不允许突发,严格平滑 | 允许窗口内突发,但窗口边界有毛刺 |
| 流量整形 | 中等(允许一定波动) | 强(完全平滑) | 弱(窗口内可集中) |
| 实现复杂度 | 中等(需定时器或延迟计算) | 中等(需队列 + 定时器) | 低(仅计数 + 时间判断) |
| 内存开销 | 低(仅维护桶状态) | 中(需队列存储等待请求) | 极低(仅一个计数器) |
| 适用场景 | API 网关、模型推理、微服务 | 网络流量整形、数据库写入限流 | 简单限流、IP 黑名单、测试环境 |
| 模型发布推荐度 | ★★★★★ | ★★★☆☆ | ★★☆☆☆ |
2.5 模型发布场景选型建议
- 首选令牌桶: 模型推理服务通常需要容忍用户突发请求(如批量测试、并发调用),令牌桶的 burst 能力天然匹配。
- 慎用漏桶: 如果模型服务对延迟极度敏感(如实时语音交互),漏桶的排队机制可能引入不可接受的等待。
- 计数器仅用于兜底: 在全局 IP 级别做粗粒度限制时,计数器实现简单、性能高,但不要作为核心限流策略。
实战经验: 在 Kubernetes 部署的模型推理服务中,通常使用 令牌桶 + 滑动窗口 的组合策略。令牌桶控制平均速率和突发,滑动窗口在秒级粒度上做二次校验,防止令牌桶在极端情况下(如时钟偏差)产生毛刺。