API限流和防滥用

本文属于《从 0 到 1 AI 产品出海知识库》中的「合规、安全与风控」章节。

对于 AI 产品出海团队来说,API 是核心交付通道——模型推理、内容生成、数据查询,几乎所有能力都通过 API 对外暴露。一旦 API 遭到滥用,后果往往是双重的:成本失控(尤其是调用大模型时,每次请求都有真实的 token 费用)和服务质量下降(正常用户的请求被挤占,响应变慢甚至超时)。

API 限流(Rate Limiting)和防滥用(Abuse Prevention)是保护这条通道的两道防线。限流解决「量」的问题——控制单位时间内的请求数;防滥用解决「质」的问题——识别并阻断恶意行为。两者配合,才能在开放 API 能力的同时,确保服务的稳定性、公平性和经济性。


一、API 限流的核心作用

1.1 成本控制

AI 产品的 API 调用通常有明确的边际成本。以 OpenAI API 为例,每次请求按 input token 和 output token 计费。如果一个免费端点被恶意高频调用,账单可能在几小时内飙升到不可承受的水平。限流是成本控制的「断路器」——在请求到达业务逻辑之前就拦住超额流量。

1.2 服务保护

没有 rate limit 的 API 就像没有门禁的大楼。一次突发流量、一个死循环的客户端、一次爬虫抓取,都可能让后端资源耗尽,影响所有用户。限流确保系统始终在可控的负载范围内运行。

1.3 公平使用

多租户场景下,限流防止单个用户或 API Key 占据过多资源。通过为不同租户、不同订阅层级设置差异化的限流配额,确保每个用户都能获得承诺的服务质量。

1.4 合规与可审计

部分行业法规要求对 API 访问实施频率控制和安全审计。例如金融类 API 需要防止暴力试探,医疗类 API 需要记录并限制异常访问频率。限流策略的日志也是安全审计的重要素材。


二、限流策略详解

API 限流的核心是选择合适的算法。不同算法在精度、内存消耗、突发流量处理上有显著差异。

2.1 固定窗口(Fixed Window)

将时间轴按固定长度(如 1 分钟、1 小时)切分为窗口,每个窗口内允许最多 N 次请求。窗口边界处计数器归零。

// 固定窗口限流伪代码
function isAllowed(key: string, limit: number, windowMs: number): boolean {
  const windowStart = Math.floor(Date.now() / windowMs) * windowMs
  const count = redis.get(`${key}:${windowStart}`)
  if (count >= limit) return false
  redis.incr(`${key}:${windowStart}`)
  redis.expire(`${key}:${windowStart}`, windowMs / 1000)
  return true
}

优点:实现简单,内存占用低。

缺点:窗口边界处可能出现 2N 请求的突发——前一窗口末尾和后一窗口开头各来了 N 次请求,间隔可能只有几秒。

2.2 滑动窗口(Sliding Window)

在固定窗口的基础上,用当前时刻前推一个窗口长度,按权重混合当前窗口和前一窗口的计数。这消除了边界突发问题。

// 滑动窗口限流伪代码
function isAllowed(key: string, limit: number, windowMs: number): boolean {
  const now = Date.now()
  const currentWindowStart = Math.floor(now / windowMs) * windowMs
  const previousWindowStart = currentWindowStart - windowMs
 
  const currentCount = redis.get(`${key}:${currentWindowStart}`) ?? 0
  const previousCount = redis.get(`${key}:${previousWindowStart}`) ?? 0
 
  // 计算前一窗口的加权比例
  const elapsed = now - currentWindowStart
  const weight = (windowMs - elapsed) / windowMs
 
  const estimatedCount = previousCount * weight + currentCount
  if (estimatedCount >= limit) return false
 
  redis.incr(`${key}:${currentWindowStart}`)
  return true
}

优点:平滑,无边界突发。

缺点:比固定窗口多一次 Redis 读取,计算略复杂。

2.3 令牌桶(Token Bucket)

以固定速率向桶中投放令牌,桶有最大容量。每次请求消耗一个令牌,桶空则拒绝。允许一定程度的突发——只要桶里有积累的令牌。

// 令牌桶限流伪代码
function isAllowed(key: string, rate: number, capacity: number): boolean {
  const now = Date.now()
  const bucket = redis.hgetall(key)
 
  const tokens = bucket.tokens ?? capacity
  const lastRefill = bucket.lastRefill ?? now
 
  // 补充令牌
  const elapsed = (now - lastRefill) / 1000
  const newTokens = Math.min(capacity, tokens + elapsed * rate)
 
  if (newTokens < 1) return false
 
  redis.hset(key, {
    tokens: newTokens - 1,
    lastRefill: now,
  })
  return true
}

优点:允许突发、平滑限流,是大多数 API 网关的默认选择。

缺点:需要存储每个 key 的桶状态(令牌数和最后填充时间)。

2.4 漏桶(Leaky Bucket)

请求以任意速率进入,但以固定速率离开(被处理)。就像一个底部有洞的桶——无论倒入多快,流出速度恒定。超出处理能力的请求被丢弃或排队。

优点:输出速率完全均匀,适合保护下游资源。

缺点:不允许任何突发,对正常用户的突发请求体验较差。

2.5 限流策略对比

维度固定窗口滑动窗口令牌桶漏桶
实现复杂度
内存占用低(每 key 一个计数器)低(每 key 两个计数器)中(需存令牌数 + 时间戳)中(需存队列或计数器)
边界突发有(最坏 2N)
突发流量不支持不支持支持(桶内积累令牌)不支持(恒定速率)
适用场景粗粒度限流、低成本场景中等精度的 API 限流API 网关默认策略保护固定吞吐的下游系统
分布式支持容易容易需要(Redis 原子操作)需要

三、限流实现方法

3.1 应用层中间件

在应用代码中实现限流逻辑,作为中间件或装饰器挂载到路由上。适合单体应用或不需要网关的场景。

// Express + Redis 滑动窗口限流中间件
import rateLimit from 'express-rate-limit'
import RedisStore from 'rate-limit-redis'
import Redis from 'ioredis'
 
const redis = new Redis(process.env.REDIS_URL!)
 
const limiter = rateLimit({
  windowMs: 60 * 1000, // 1 分钟
  max: 60, // 每分钟 60 次
  standardHeaders: true, // 返回 X-RateLimit-* 头
  legacyHeaders: false,
  store: new RedisStore({
    sendCommand: (...args) => redis.call(...args),
  }),
  keyGenerator: (req) => {
    // 按 API Key 或 IP 限流
    return req.headers['x-api-key'] ?? req.ip
  },
  handler: (req, res) => {
    res.status(429).json({
      error: 'Too Many Requests',
      retryAfter: res.getHeader('Retry-After'),
    })
  },
})
 
app.use('/api/', limiter)

注意:应用层限流的前提是请求已经到达应用服务器。如果流量大到把服务器打满,应用层限流本身也会失效。

3.2 API 网关层

在 API 网关(如 Kong、AWS API Gateway、Cloudflare)上配置限流策略,请求到达应用之前就已被拦截。这是生产环境的主流做法。

# Kong Rate Limiting Plugin 配置示例
plugins:
  - name: rate-limiting
    config:
      minute: 60
      hour: 1000
      policy: redis
      redis_host: redis.internal
      redis_port: 6379
      limit_by: consumer  # 按 API Consumer 限流
      hide_client_headers: false
      strategy: fixed-window  # 或 sliding-window

网关层限流的优势:

  • 集中管理:一个地方配置所有路由的限流策略
  • 高性能:网关通常用 Lua / C 实现,限流逻辑开销极低
  • 分布式:天然支持多节点共享限流状态

3.3 客户端配合

限流不只是服务端的事。客户端(SDK、前端)也需要配合处理限流响应:

// 客户端限流重试逻辑
async function callApiWithRetry(
  url: string,
  options: RequestInit,
  maxRetries = 3,
): Promise<Response> {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, options)
 
    if (response.status === 429) {
      // 读取 Retry-After 头,退避后重试
      const retryAfter = response.headers.get('Retry-After')
      const delay = retryAfter ? parseInt(retryAfter) * 1000 : Math.pow(2, attempt) * 1000
      await new Promise((resolve) => setTimeout(resolve, delay))
      continue
    }
 
    return response
  }
  throw new Error('Max retries exceeded')
}

3.4 实现方法对比

维度应用层中间件API 网关层CDN/边缘层
拦截位置应用服务器网关(应用之前)边缘节点(最近用户)
性能开销中(占用应用资源)低(专用组件)极低(边缘计算)
分布式支持需要 Redis 等外部存储通常内置天然分布式
灵活度高(可定制任意逻辑)中(插件/配置驱动)低(规则驱动)
适用阶段MVP / 小规模Growth / 中等规模全球分发 / 大规模
典型工具express-rate-limit、SlowAPIKong、AWS API GatewayCloudflare、Fastly

四、防滥用措施

限流控制「量」,防滥用控制「质」。一个恶意用户可以在限流配额内做出各种有害行为——爬取数据、试探漏洞、批量注册、注入攻击。防滥用措施需要更深层的行为分析。

4.1 身份验证与授权

所有 API 请求都应该有身份标识。匿名访问的防滥用能力极弱,因为无法追踪和区分用户。

// API Key 认证中间件
async function authenticateApiKey(req: Request): Promise<ApiKeyInfo> {
  const key = req.headers.get('x-api-key')
  if (!key) throw new UnauthorizedError('Missing API Key')
 
  const keyInfo = await db.apiKeys.findOne({ key: hash(key) })
  if (!keyInfo) throw new UnauthorizedError('Invalid API Key')
  if (keyInfo.revokedAt) throw new UnauthorizedError('API Key revoked')
 
  // 检查 Key 的权限范围
  return keyInfo
}

4.2 行为分析与异常检测

基于请求模式识别滥用行为:

  • 频率异常:某用户突然从每分钟 5 次请求跳到每分钟 200 次
  • 路径异常:短时间内遍历大量不同端点(扫描行为)
  • 参数异常:请求参数中包含 SQL 注入、XSS payload 等特征
  • 地理异常:同一 API Key 在短时间从多个不同国家发起请求
  • 时间异常:在非工作时间段出现异常高频请求
// 简化的异常检测逻辑
interface RequestLog {
  apiKeyId: string
  timestamp: number
  path: string
  statusCode: number
}
 
function detectAnomaly(recentLogs: RequestLog[]): Anomaly | null {
  const oneMinuteAgo = Date.now() - 60_000
 
  // 检查 1 分钟内的请求数
  const recentCount = recentLogs.filter((l) => l.timestamp > oneMinuteAgo).length
  if (recentCount > 100) {
    return { type: 'FREQUENCY_SPIKE', severity: 'high', count: recentCount }
  }
 
  // 检查是否遍历大量不同路径
  const uniquePaths = new Set(recentLogs.map((l) => l.path))
  if (uniquePaths.size > 50) {
    return { type: 'PATH_SCANNING', severity: 'medium', uniquePaths: uniquePaths.size }
  }
 
  // 检查大量 4xx 错误(可能是暴力试探)
  const errorCount = recentLogs.filter((l) => l.statusCode >= 400).length
  if (errorCount > 30) {
    return { type: 'HIGH_ERROR_RATE', severity: 'high', errorCount }
  }
 
  return null
}

4.3 黑名单与白名单

  • IP 黑名单:封禁已知恶意 IP。适合处理已识别的攻击源,但 IP 容易更换。
  • API Key 黑名单:吊销被发现滥用的 API Key。
  • 白名单:对可信合作伙伴开放更高限额或免限流。

4.4 请求签名与防重放

对于高价值 API(如支付、模型推理),需要防止请求被截获后重放。常见做法是在请求中加入时间戳和签名:

// HMAC 请求签名
function signRequest(body: string, secret: string, timestamp: number): string {
  const payload = `${timestamp}:${body}`
  return crypto.createHmac('sha256', secret).update(payload).digest('hex')
}
 
// 服务端验证
function verifySignature(
  body: string,
  secret: string,
  timestamp: number,
  signature: string,
): boolean {
  // 拒绝超过 5 分钟的旧请求
  if (Date.now() - timestamp > 5 * 60 * 1000) return false
 
  const expected = signRequest(body, secret, timestamp)
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected),
  )
}

4.5 防滥用措施对比

措施防护目标实现成本误判风险推荐阶段
API Key 认证身份识别、配额隔离所有阶段
IP 限流分布式攻击、匿名滥用中(NAT 后多用户共享 IP)所有阶段
行为分析异常模式检测Growth 及以上
IP 黑名单已知攻击源辅助手段
请求签名防重放、防篡改高价值 API
CAPTCHA / 挑战自动化机器人中(影响正常用户体验)公开端点
WAF 规则SQL 注入、XSS 等所有阶段

五、监控与告警

限流和防滥用策略的有效性取决于监控。没有监控,就无法知道策略是否合理、是否正在遭受攻击、是否误伤了正常用户。

5.1 核心监控指标

指标类别具体指标说明
流量指标请求总数 / QPS按路由、API Key、IP 维度统计
限流指标429 响应数 / 429 占比反映限流策略是否触发过紧
错误指标4xx / 5xx 错误率异常升高通常意味着攻击或故障
延迟指标P50 / P95 / P99 延迟性能劣化可能是滥用或资源耗尽的前兆
业务指标按租户的请求分布检查是否有租户超比例使用资源
安全指标认证失败次数高频认证失败可能意味着暴力破解

5.2 异常检测与自动响应

# Prometheus 告警规则示例
groups:
  - name: api-abuse-alerts
    rules:
      # 某 API Key 的 429 响应突然增加
      - alert: HighRateLimitRejections
        expr: |
          sum(rate(http_responses_total{status="429"}[5m])) by (api_key) > 10
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "API Key {{ $labels.api_key }} 频繁触发限流"
 
      # 认证失败率异常
      - alert: HighAuthFailureRate
        expr: |
          sum(rate(http_responses_total{status="401"}[5m])) /
          sum(rate(http_requests_total[5m])) > 0.1
        for: 3m
        labels:
          severity: critical
        annotations:
          summary: "认证失败率超过 10%,可能存在暴力破解"
 
      # 单 IP 请求量异常
      - alert: SingleIPHighTraffic
        expr: |
          sum(rate(http_requests_total[5m])) by (client_ip) > 100
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "IP {{ $labels.client_ip }} 请求频率异常"

5.3 自动响应机制

当告警触发时,可以采取自动措施:

  • 动态收紧限流:检测到攻击流量时,自动降低受影响端点的限流阈值
  • 自动封禁:将触发多个安全告警的 IP 或 API Key 加入临时黑名单
  • 降级策略:在资源紧张时,优先保障付费用户的请求,拒绝免费用户的非关键请求
  • 通知值班人员:通过 Slack、PagerDuty 等渠道及时通知

六、工具推荐

6.1 API 网关与限流平台

工具类型限流算法部署方式适用规模定价模式
Kong Gateway开源 API 网关固定窗口、滑动窗口自托管 / 云托管中大规模开源免费,Enterprise 按量
AWS API Gateway云服务固定窗口全托管中大规模按请求数 + 数据传输
CloudflareCDN + WAF + 限流固定窗口、滑动窗口边缘(全球)大规模免费层 + Pro/Business 订阅
Tyk开源 API 网关令牌桶、滑动窗口自托管 / 云托管中大规模开源免费,Cloud 按量
UpstashServerless Redis令牌桶(SDK 实现)全托管小到中规模按命令数
express-rate-limitNode.js 中间件固定窗口、滑动窗口应用内嵌MVP / 小规模免费开源

6.2 监控与告警

工具用途特点
Prometheus + Grafana指标监控 + 可视化开源标准,生态丰富
Datadog全栈监控APM + 日志 + 指标一体,AI 产品有现成 Dashboard
Grafana Cloud托管监控基于 Prometheus/Loki/Tempo,免运维
Sentry错误追踪异常请求和错误率监控

6.3 选型建议

  • MVP 阶段express-rate-limit + Redis,成本低,几小时就能上线
  • Growth 阶段:引入 Kong 或 AWS API Gateway,配合 Prometheus + Grafana 做监控
  • Scale 阶段:Cloudflare 边缘限流 + API 网关精细控制 + Datadog 全栈监控

七、案例分析

7.1 案例一:AI 写作助手的 API 滥用事件

背景:一个提供 AI 写作能力的 SaaS 产品,对外暴露文本生成 API。免费层用户每天可调用 50 次,付费层按使用量计费。

问题

  • 上线第三周,后端 LLM 调用费用突然翻了 5 倍
  • 排查发现某个免费层 API Key 以每分钟 30 次的频率持续调用长文本生成接口
  • 该用户通过拆分请求绕过每日 50 次的限制——每次请求的参数略有不同,实际上是在拼接一本完整小说
  • 由于是长文本生成,每次调用消耗大量 token,成本远高于短文本请求

改进

  1. 增加 token 维度的限流——不只是限制请求次数,还限制每分钟消耗的总 token 数
  2. 引入滑动窗口算法替换固定窗口,消除边界突发
  3. 在 API 网关(Kong)层统一配置限流策略,而不是在应用代码中
  4. 设置成本告警——当单日 LLM 调用费用超过预算 150% 时自动通知
  5. 对长文本生成接口设置更严格的限流(每分钟 3 次),短文本接口保持宽松

效果:月度 API 成本降低 60%,正常用户的 P99 延迟从 8 秒降到 3 秒。

7.2 案例二:多租户 AI 图像生成平台的公平性保障

背景:一个面向设计师的 AI 图像生成平台,有 200+ 企业租户,每个租户有不同的订阅层级(Starter / Pro / Enterprise)。

问题

  • Enterprise 租户反馈在高峰期生成速度明显变慢
  • 排查发现部分 Starter 租户在高峰期集中提交批量任务,占用了 GPU 资源
  • 固定窗口限流导致整点时刻流量突增,GPU 利用率波动剧烈
  • 没有按租户层级的差异化限流,所有租户共享相同的限流配额

改进

  1. 实施分层限流——Starter: 10 次/分钟,Pro: 30 次/分钟,Enterprise: 100 次/分钟
  2. 将限流算法从固定窗口改为令牌桶,平滑 GPU 资源消耗
  3. 引入优先级队列——Enterprise 租户的请求优先调度
  4. 在 API 网关层增加请求排队机制,超出限流的请求不直接返回 429,而是在队列中等待(最长 30 秒)
  5. 建立租户级别的用量 Dashboard,租户可以在控制台看到自己的实时用量和配额

效果:Enterprise 租户的 P95 延迟稳定在 5 秒以内,租户投诉减少 80%。分层限流也让销售团队能够用「更高限额」作为升级卖点。


八、API 限流与防滥用流程

适读画布 · 130%
Mermaid 流程图加载中...

九、上线前检查清单

  • 选择限流算法:根据业务特点选择固定窗口、滑动窗口、令牌桶或漏桶,不要用默认配置了事
  • 多维度限流:至少按 API Key 和 IP 两个维度限流,高价值接口增加 token / 数据量维度
  • 分层配额:按订阅层级设置差异化限流配额,免费层要严格限制
  • 返回标准响应头:所有响应包含 X-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-Reset,被限流时返回 Retry-After
  • 429 响应格式:返回结构化的 JSON 错误体,包含错误原因和重试建议
  • 分布式限流状态:使用 Redis 等共享存储确保多实例间限流状态一致
  • 认证强制:所有 API 端点要求认证,不接受匿名访问(公开文档端点除外)
  • 异常检测:部署行为分析逻辑,能检测频率突增、路径扫描、高错误率等异常模式
  • 监控仪表盘:搭建包含请求量、429 占比、错误率、P95 延迟的监控面板
  • 告警规则:配置关键告警——限流触发率突增、认证失败率异常、单 IP / Key 流量异常
  • 自动响应:至少有一种自动响应机制(动态收紧限流、自动封禁、降级策略)
  • 客户端重试:SDK 和文档中说明 429 的处理方式,推荐指数退避重试
  • 压测验证:上线前用压测工具验证限流策略在不同负载下的表现
  • 文档透明:在 API 文档中公开限流配额,让调用方知道限制在哪里

十、参考资料

  1. Rate Limiting Best Practices in REST API Design — Speakeasy
  2. 10 Best Practices for API Rate Limiting in 2026 — Zuplo
  3. From Token Bucket to Sliding Window: Pick the Perfect Rate Limiting — API7.ai
  4. Rate Limiting Algorithms: Token Bucket vs Sliding Window vs Fixed — Arcjet
  5. What is API Abuse and How Can You Prevent It? — Wiz
  6. Real-time API Abuse Prevention for SaaS and AI Platforms — Stripe
  7. API Rate Limiting: A Beginner's Guide — Kong
  8. Rate Limiting Best Practices — Cloudflare Docs
  9. 设计一个限流器 — 系统设计面试:内幕指南
  10. 大规模分布式架构中,怎样设计和选择 API 限流技术? — InfoQ

小结:API 限流和防滥用是 AI 产品出海的基础设施层能力。限流算法(令牌桶是大多数场景的最佳默认)控制请求量,防滥用措施(认证 + 行为分析 + 自动响应)控制请求质量,监控告警(Prometheus + Grafana 或 Datadog)提供可见性。三者缺一不可——没有限流的防滥用是亡羊补牢,没有防滥用的限流是形同虚设,没有监控的两者是盲人摸象。从 MVP 阶段的 express-rate-limit + Redis 开始,逐步演进到 API 网关 + 边缘限流 + 全栈监控的成熟方案。