跳转到内容
Guide

API 速率限制:每个开发人员都应该知道的 4 种算法

| 9 min read

固定窗口、滑动窗口、令牌桶和漏桶通过图表、X-RateLimit 标头和可复制粘贴的 Node.js 重试逻辑进行了说明。

Data visualization with streaming lines and analytics
Photo by Joshua Sortino on Unsplash

您的批处理作业在 3 秒内触发 200 个请求,并且每个响应都会返回 429 Too Many Requests。 您的 Webhook 处理器攻击第三方 API,并被阻止 15 分钟。 客户的集成 变得沉默,因为他们的重试循环在第一个小时内耗尽了每日配额。 这些失败的经历分享 根本原因之一:代码不遵守速率限制。

本指南涵盖了四种核心速率限制算法,向您展示如何阅读 X-RateLimit 来自任何 API 的标头,并为您提供复制粘贴 Node.js 代码,以实现具有指数退避的重试逻辑。

四种限速算法

每个速率限制器都会回答相同的问题:“该请求应该通过,还是应该拒绝?” 这四种算法的不同之处在于跟踪时间和处理突发的方式。

1.固定窗

最简单的方法。 将时间分成固定的间隔(例如 1 分钟)。 每个时间间隔的请求计数。 当计数达到限制时,拒绝所有内容,直到下一个间隔开始。

固定窗口很容易构建:每个客户端一个计数器和一个时间戳。 缺点是 边界问题。 客户端可以在一个窗口结束时发送完整限额以及完整限额 在下一个开始时,在短时间内获得预期速率的 2 倍。 GitHub 的旧 API 使用固定窗口的速率限制器; 此后他们转向了更复杂的方法。

2. 滑动窗口

窗口不是在固定边界处重置,而是随着每个请求而滑动。 在任何特定时刻, 限制器回顾过去 N 秒并计算该范围内的请求。

滑动窗口消除了边界突发问题。 成本更高的内存:您存储时间戳 对于每个请求,而不是一个计数器。 雷迪斯 ZRANGEBYSCORE 使其大规模实用。 Cloudflare 和许多 API 网关使用滑动窗口来限制每用户的速率。

3、令牌桶

想象一个装有代币的桶。 每个请求花费一个令牌。 代币以固定速率补充。 如果存储桶为空,则请求将被拒绝。 如果桶已满,多余的令牌就不会累积。

令牌桶是生产中最流行的算法。 Stripe、AWS API Gateway 和大多数云 提供商使用它的变体。 桶容量控制爆破大小,再填充率控制 持续的吞吐量。 两个参数可让您对流量形状进行细粒度控制。

4.漏桶

令牌桶的逆。 请求填满了一个桶。 桶以恒定的速度排水。 如果 桶溢出,多余的请求被拒绝。 无论输入如何,输出速率都保持恒定 爆发。

漏桶非常适合需要稳定输出速率的流量整形:队列工作人员、 Webhook 交付和视频编码管道。 权衡是突发会排队而不是 比服务; 负载下延迟会增加。

比较四种算法

算法 允许爆裂吗? 记忆 常见用例
固定窗 边缘突发(边界处 2x) 低(1 个计数器) 简单的计数器、分析
推拉窗 平滑,无边界尖峰 中(每个请求时间戳) 每用户 API 限制
令牌桶 受控突发容量 低(2 个值) 大多数生产 API(Stripe、AWS)
漏水桶 排队、恒定输出速率 中(队列) 流量整形、队列工作者

读取 X-RateLimit 标头

大多数 API 都在响应标头中包含速率限制信息。 三个标题告诉你一切 您需要保持在限制以下:

  • X-RateLimit-Limit:每个窗口允许的最大请求数
  • X-RateLimit-Remaining:您在当前窗口中留下的请求
  • X-RateLimit-Reset:窗口重置时的 Unix 时间戳(秒)

当超过限制时,响应状态为 429 Too Many RequestsRetry-After 标题告诉您要等待多少秒。

尝试使用 botoi 的 API。 此curl命令对字符串进行哈希处理并打印速率限制标头:

响应头:

这告诉您每个窗口的限制是 5 个请求,在此请求之后您还剩下 4 个请求,并且 窗口在给定的 Unix 时间戳处重置。 在 HTTP 客户端中跟踪这些值以避免命中 首先是429。

提示: 转变 X-RateLimit-Reset 等待时间: waitMs = (resetTimestamp - Math.floor(Date.now() / 1000)) * 1000

Node.js 中使用指数退避重试逻辑

当 429 命中时,不要立即重试。 紧密的重试循环会使问题变得更糟:你留下来 速率限制时间更长,服务器会将您标记为滥用行为。 请改用带有抖动的指数退避。

将其与任何端点一起使用:

该函数检查 Retry-After 首先是标题。 如果服务器告诉你需要多长时间 等待,尊重它。 如果不存在标头,则回退到指数退避:1 秒、2 秒, 4秒,8秒。 随机抖动(0-500ms)可防止雷群问题,其中数百个 客户端在同一时刻重试。

主动限制:在 429 发生之前避免它们

反应式重试在故障发生后对其进行处理。 主动节流可以防止它们。 如果你知道 速率限制(来自文档或标头),调整客户端的请求速度。

该客户端速率限制器在滑动窗口中跟踪请求时间戳。 在每次请求之前, 它检查窗口是否已满,并在需要时等待。 您在最大安全范围内发送请求 没有一个429的率。

Botoi的速率限制模型

Botoi 使用两层速率限制系统:

计划 突发(每分钟) 配额 授权
免费(0 美元) 5 请求/分钟 100/天 无(基于 IP)
入门版($9/月) 30 请求/分钟 30万/月 API密钥
专业版($49/月) 300 请求/分钟 3,000,000/月 API密钥
商务($199/月) 1,000 请求/分钟 30,000,000/月 API密钥

匿名访问通过 IP 地址跟踪请求。 每日计数在 UTC 午夜通过 Cloudflare KV 计数器。 经过身份验证的请求使用 API 密钥进行识别和限制 是通过执行 取消密钥的 边缘的令牌桶速率限制器。

每一条回复都来自 api.botoi.com 包括三个 X-RateLimit 标头 如上所述,因此无论计划如何,您的重试逻辑都会以相同的方式工作。

经验证的 API 消费者方法

  • 阅读每个回复的标题。 不要从文档中硬编码速率限制。 API 更改限制,恕不另行通知。 标题是事实的来源。
  • 使用带有抖动的指数退避。 固定重试间隔导致同步 跨客户端重试。 抖动会分散负载。
  • 在 API 支持的情况下进行批处理。 1 个请求包含 10 个项目,费用为 1 个速率限制 令牌。 十个单独请求的费用为 10。
  • 缓存响应。 如果数据在请求之间没有改变,则存储结果 并跳过 API 调用。 DNS 记录、SSL 证书和 WHOIS 数据很少在几分钟内发生变化。
  • 使用队列进行后台工作。 不要从热循环中触发 API 调用。 推 在队列(BullMQ、SQS、Cloudflare 队列)上工作并以受控速率处理项目。
  • 监控您的剩余配额。 日志 X-RateLimit-Remaining 给你的 指标仪表板。 当低于限制的 20% 时设置警报。

要点

  • 四种算法占主导地位。 固定窗最简单。 令牌桶最为流行。 滑动窗口消除了边界突发。 漏桶平滑输出。
  • X-RateLimit 标头是您的 API。Limit, Remaining, 和 Reset 对每一个回应都保持在上限之下。
  • 抖动处理的指数退避为 429s。 复制 fetchWithRetry 将上面的函数添加到您的代码库中并包装每个外部 API 调用。
  • 主动限制可防止 429 错误。 在客户端调整您的请求 而不是等待服务器推回。
  • 无需帐户即可测试。 击中任意 botoi 端点 api.botoi.com 每分钟 5 个免费请求,可查看正在运行的速率限制标头。

FAQ

什么是 API 速率限制以及 API 为何使用它?
速率限制限制了客户端在一个时间窗口内可以发出的请求数量。 API 使用它来保护服务器免于过载,防止滥用,确保客户端之间公平的资源共享,并保持基础设施成本可预测。 没有它,一个客户就可能让其他所有客户挨饿。
X-RateLimit 标头的含义是什么?
X-RateLimit-Limit 是每个窗口允许的最大请求数。 X-RateLimit-Remaining 是您还剩下多少。 X-RateLimit-Reset 是窗口重置时的 Unix 时间戳。 Retry-After(429 响应)告诉您重试之前需要等待多少秒。
我应该如何处理 429 Too Many Requests 响应?
读取 Retry-After 标头并等待几秒钟。 如果不存在 Retry-After 标头,请使用指数退避:在第一个 429 之后等待 1 秒,在第二个之后等待 2 秒,在第三个之后等待 4 秒,依此类推。 添加随机抖动(0-500ms)以防止当许多客户端同时重试时出现惊群问题。
哪种速率限制算法最常见?
令牌桶是生产 API 中最常见的。 Stripe、AWS 和大多数云提供商都使用它的变体。 令牌桶允许控制突发,同时强制执行持续速率,这比固定窗口更好地匹配实际流量模式。
botoi 速率是否限制匿名请求?
是的。 匿名请求(无 API 密钥)每分钟突发 5 个请求,每天 100 个请求,按 IP 地址跟踪。 付费计划的经过身份验证的请求获得更高的限制:Starter 允许 30 个/分钟,Pro 允许 300 个/分钟,Business 允许 1,000 个/分钟。

开始使用 botoi 构建

150+ 个 API 端点,涵盖查询、文本处理、图片生成和开发者工具。免费套餐,无需信用卡。