2. 流量整形基础概念:令牌桶算法、漏桶算法、滑动窗口、队列与背压机制
流量整形(Traffic Shaping)是 API 网关与模型推理服务之间最重要的流量控制手段。在模型风险控制场景中,大模型推理的算力成本高、响应时间敏感,突发的请求洪峰不仅会导致服务雪崩,还可能引发推理质量下降或安全策略失效。本章深入剖析四种核心整形机制的原理、适用场景与工程实现要点。
2.1 令牌桶算法(Token Bucket)
令牌桶算法是业界最广泛使用的流量整形算法。它通过一个虚拟的“桶”来平滑突发流量,允许短时间内的突发请求,同时保证长期平均速率不超过预设阈值。
核心原理: 系统以固定速率向桶中添加令牌,每个请求必须消耗一个令牌才能被处理。桶的容量限制了最大突发量。
关键参数与工程配置
| 参数 | 符号 | 说明 | 模型推理场景建议 |
|---|---|---|---|
| 令牌填充速率 | r | 每秒向桶中添加的令牌数,决定长期平均速率 | 根据模型 QPS 上限 × 安全系数(0.7~0.8) |
| 桶容量 | B | 桶最多容纳的令牌数,决定最大突发量 | B = r × 允许突发秒数(通常 2~5 秒) |
| 每次请求消耗 | c | 处理一个请求消耗的令牌数 | 可根据请求复杂度动态调整(如长文本消耗 2 个令牌) |
模型风险控制提示: 对于大模型推理,建议将令牌桶与请求复杂度绑定。例如,简单问答消耗 1 个令牌,长文本生成消耗 3 个令牌,图像生成消耗 5 个令牌。这样可以更精细地控制算力消耗。
2.2 漏桶算法(Leaky Bucket)
漏桶算法与令牌桶的核心区别在于:漏桶强制输出速率恒定,不允许突发。它像一个底部有漏洞的水桶,无论进水多快,出水始终保持固定速率。
| 对比维度 | 令牌桶算法 | 漏桶算法 |
|---|---|---|
| 输出特性 | 允许突发,但长期平均受限 | 完全平滑,输出速率严格恒定 |
| 适用场景 | 允许短时突发的业务(如搜索、对话) | 要求绝对平滑的流式输出(如视频流、实时推理) |
| 实现复杂度 | 中等(需维护定时器或计数器) | 较低(队列 + 固定速率消费) |
| 对突发流量的处理 | 允许突发,但桶满后丢弃 | 请求进入队列,超出队列容量则丢弃 |
工程注意: 漏桶算法在模型推理中可能导致请求排队时间过长。如果队列深度设置不当,用户等待时间会线性增长。建议将漏桶与超时机制结合,队列中的请求超过最大等待时间(如 30 秒)直接丢弃并返回 503。
2.3 滑动窗口(Sliding Window)
滑动窗口算法通过统计一个动态时间窗口内的请求数量来实现限流。它解决了固定窗口算法的“临界突变”问题,能够更平滑地控制流量。
三种实现方式对比
| 实现方式 | 精度 | 内存开销 | 适用场景 |
|---|---|---|---|
| 滑动日志 | 最高(精确到毫秒) | 高(需存储每个请求时间戳) | 高精度限流,请求量较小 |
| 滑动窗口计数 | 中等(窗口分片) | 低(仅存储分片计数器) | 生产环境最常用 |
| 滑动窗口 + 令牌桶 | 高 | 中等 | 需要同时控制速率和突发 |
滑动窗口 vs 固定窗口: 固定窗口在窗口切换瞬间可能出现 2 倍流量突增(如 0:59 和 1:00 各 100 次请求,实际 1 秒内 200 次)。滑动窗口通过分片加权计算,将误差控制在单个分片粒度内。
2.4 队列与背压机制(Queue & Backpressure)
队列是流量整形中最直接的缓冲手段。当请求速率超过处理能力时,请求进入队列等待。背压机制则是队列的“反向信号”——当下游处理能力不足时,向上游传递压力信号,让上游主动降速。
队列类型与选择
| 队列类型 | 特点 | 模型推理适用性 |
|---|---|---|
| 有界队列(Bounded Queue) | 固定容量,满则丢弃或阻塞 | 推荐,防止内存溢出 |
| 无界队列(Unbounded Queue) | 可无限增长 | 不推荐,可能导致 OOM |
| 优先级队列 | 按优先级出队 | 适合 VIP 用户或紧急请求 |
| 延迟队列 | 指定延迟时间后出队 | 适合重试场景 |
背压机制的三种实现模式
- 同步背压: 下游处理完一个请求后,上游才发送下一个。适用于请求量小、延迟敏感的场景。
- 异步背压(Reactive Streams): 下游通过 Subscription 向上游请求 N 个元素,上游最多发送 N 个。适用于高吞吐流式推理。
- 动态背压: 下游实时反馈处理速率,上游动态调整发送速率。适用于负载波动大的生产环境。
2.5 四种机制的综合选型建议
| 场景 | 推荐算法 | 原因 |
|---|---|---|
| 对话式 AI(允许短时突发) | 令牌桶 + 有界队列 | 允许用户连续提问,同时保护后端 |
| 流式文本生成(SSE) | 漏桶 + 背压 | 输出速率恒定,避免客户端缓冲区溢出 |
| 多租户 API 网关 | 滑动窗口 + 令牌桶 | 精确控制每个租户的 QPS,防止互相干扰 |
| 批量推理任务 | 有界队列 + 背压 | 任务排队等待,背压防止任务堆积过多 |
生产环境最佳实践: 建议将令牌桶算法作为第一道防线(网关层),滑动窗口作为第二道防线(租户级限流),队列 + 背压作为第三道防线(服务层)。三层防护可以覆盖绝大多数流量整形需求。