2. 限流基础概念

2.1 什么是API限流

API限流(Rate Limiting)是一种控制客户端在指定时间窗口内能够向服务端发送请求数量的机制。在模型验证环境中,大模型推理资源昂贵且响应时间敏感,限流能够防止单个用户或接口耗尽集群算力,保障核心业务的可用性。

核心目标: 保护后端服务不被突发流量冲垮,确保资源公平分配,维持SLA承诺的响应延迟。

限流与熔断的区别:限流是主动控制请求进入速率,熔断是被动检测故障后切断请求链路。两者常配合使用,形成“先限流、后熔断”的防御层次。

2.2 常见限流算法

业界主流限流算法包括令牌桶、漏桶和计数器三种,它们在突发处理、平滑度和实现复杂度上各有侧重。

算法 核心原理 突发处理 平滑度 典型场景
令牌桶 以固定速率向桶中放入令牌,请求需获取令牌才能通过 允许一定突发 中等 允许短时突发的API网关
漏桶 请求以固定速率从桶底漏出,超出桶容量的请求被丢弃 严格拒绝突发 高 数据库连接池、消息队列
计数器 在固定时间窗口内统计请求数,超过阈值则拒绝 窗口边界易突发 低 简单限流、测试环境快速验证

令牌桶算法详解

令牌桶是模型验证环境中最常用的限流算法。系统以恒定速率(如每秒10个)向桶中添加令牌,桶容量上限(如20个)决定了最大突发量。每个请求到达时从桶中取走一个令牌,若桶空则请求被阻塞或拒绝。

# 令牌桶核心逻辑(伪代码)
class TokenBucket:
    def __init__(self, rate, capacity):
        self.rate = rate          # 令牌生成速率(个/秒)
        self.capacity = capacity  # 桶容量
        self.tokens = capacity    # 当前令牌数
        self.last_refill = time.time()

    def allow_request(self):
        now = time.time()
        elapsed = now - self.last_refill
        self.tokens = min(self.capacity, self.tokens + elapsed * self.rate)
        self.last_refill = now
        if self.tokens >= 1:
            self.tokens -= 1
            return True
        return False

漏桶算法详解

漏桶算法将请求视为水滴,以固定速率从桶底流出。桶容量固定,超出容量的请求直接丢弃。该算法强制输出速率恒定,适合需要严格平滑流量的场景。

# 漏桶核心逻辑(伪代码)
class LeakyBucket:
    def __init__(self, rate, capacity):
        self.rate = rate          # 漏水速率(请求/秒)
        self.capacity = capacity  # 桶容量
        self.water = 0            # 当前水量
        self.last_leak = time.time()

    def allow_request(self):
        now = time.time()
        leaked = (now - self.last_leak) * self.rate
        self.water = max(0, self.water - leaked)
        self.last_leak = now
        if self.water < self.capacity:
            self.water += 1
            return True
        return False

计数器算法详解

计数器算法实现最简单:在固定时间窗口(如1秒)内统计请求次数,超过阈值则拒绝。缺点是窗口切换瞬间可能出现两倍阈值的突发流量。

注意: 计数器算法在模型验证环境中仅适用于低精度要求的场景。若需要更精确的限流,建议使用滑动窗口计数器或令牌桶算法。
三种限流算法核心流程对比 令牌桶 ① 固定速率生成令牌 ② 令牌存入桶中(容量上限) ③ 请求到达,取令牌 ④ 有令牌→放行 ⑤ 无令牌→拒绝/等待 允许突发 桶容量=最大突发量 漏桶 ① 请求进入桶中 ② 桶满→丢弃请求 ③ 固定速率从桶底漏出 ④ 请求按恒定速率流出 ⑤ 输出完全平滑 严格拒绝突发 输出速率恒定 计数器 ① 定义时间窗口(如1s) ② 窗口内请求数+1 ③ 未超阈值→放行 ④ 超阈值→拒绝 ⑤ 窗口重置,计数归零 窗口边界突发 实现最简单

2.3 限流粒度

限流粒度决定了限流规则的作用范围。在模型验证环境中,通常需要从全局、用户、接口三个维度进行精细化控制。

粒度 作用范围 典型阈值 模型验证场景示例
全局 整个API网关或服务集群 1000 QPS 保护GPU集群不因总请求过载而OOM
用户 单个API Key或用户ID 100 QPS/用户 防止单个测试脚本占用全部推理资源
接口 特定API端点(如 /v1/chat/completions) 50 QPS/接口 对高消耗的流式接口单独限流
最佳实践: 在模型验证环境中,建议采用“全局+用户+接口”三层限流叠加策略。全局限流保护集群,用户限流保障公平,接口限流精细化控制不同模型端点的资源消耗。
三层限流粒度架构 全局限流 集群总QPS上限:1000 req/s 用户限流 每个API Key独立配额:100 req/s 接口限流 /v1/chat/completions: 50 req/s | /v1/embeddings: 200 req/s | /v1/rerank: 100 req/s

2.4 限流算法选型建议

在模型验证环境中,不同场景适合不同的限流算法组合:

  • 高并发推理接口: 令牌桶 + 用户粒度限流,允许短时突发,提升用户体验。
  • 流式输出接口: 漏桶 + 接口粒度限流,保证输出速率稳定,避免客户端缓冲区溢出。
  • 内部测试环境: 计数器 + 全局粒度限流,实现简单,快速验证限流逻辑是否正确。
  • 多模型混合部署: 令牌桶 + 接口粒度限流,为不同模型设置差异化配额。
关键指标: 限流配置上线前需进行压力测试,验证限流阈值是否准确。建议使用滑动窗口计数器作为基准测试工具,对比不同算法的实际限流效果。