公共 API 的速率限制:实用配额与锁定流程
为公共 API 设定速率限制,既能阻止滥用又不阻碍真实用户:实用限制、按键配额、锁定与发布建议。

速率限制实际上在解决什么问题
公共 API 的速率限制并不是为了惩罚用户。它是一个安全阀,在流量出现异常时(无论是恶意还是客户端错误)保持服务可用。
“滥用”一开始常常看起来很正常:遍历每个端点以复制数据的爬虫、暴力破解登录尝试、针对认证路由的令牌填充,或是在超时后紧密重试同一请求的失控客户端。有时根本没有人攻击你。一次移动应用更新带来错误的缓存规则,突然每台设备每秒轮询你的 API。
目标很直接:保护正常运行时间并控制成本,同时不阻挡真实用户的正常操作。如果你的后端是计量收费的(计算、数据库、邮件/SMS、AI 调用),一个吵闹的行为者就可能迅速把账单推高。
仅有速率限制还不够。没有监控和清晰的错误响应,你会得到无声失败、困惑的客户以及听起来像“你们的 API 宕机了”的支持工单,而实际上只是被限流了。
一个完整的保护通常由几部分组成:
- 速率限制:短窗口的上限(每秒/每分钟),用来阻止突发流量。
- 配额:较长窗口的配额(每日/月度),让使用可预测。
- 锁定:针对明显滥用模式的临时封禁。
- 例外:为可信集成、内部工具或 VIP 客户放行列表。
如果你在像 AppMaster 这样的工具上构建 API 后端,这些规则同样重要。即使代码清晰且自动生成,你也需要保护性默认值,以免一个坏客户端拖垮整个服务。
关键词:速率限制、配额、节流与锁定
这些术语经常混用,但它们解决不同问题,并且对用户的感受不同。
速率限制、配额与并发:各自含义
速率限制是速度上限:客户端在短窗口内可以发出的请求数(每秒、每分钟)。配额是预算:在较长周期内的总使用量(每日、每月)。并发限制限制同时进行的请求数,这对昂贵的端点非常有用,即使请求速率看起来正常。
你把限制绑定在哪里很重要:
- 按 IP:简单,但会惩罚共享网络(办公室、学校、移动运营商)。
- 按用户:对已登录应用很好,但依赖可靠的身份识别。
- 按 API 密钥:公开 API 常用,拥有明确的归属,便于说明问题。
- 按端点:当某个路由比其他路由重得多时很有用。
节流 vs 阻断,以及锁定的位置
软节流会放慢客户端(延迟、降低突发能力),使其能在不破坏工作流程的情况下恢复。硬阻断立即拒绝请求,通常返回 HTTP 429。
锁定比普通的 429 更强。429 表示“稍后再试”。锁定则表示“在满足某个条件之前停止”,例如冷却期、人工审核或重置密钥。把锁定保留给明确的滥用信号(凭证填充、激进爬虫、重复无效认证),不要用于正常的流量峰值。
如果你用像 AppMaster 的工具构建 API,把这些当作独立控制:短窗口限制用于突发,较长配额用于成本控制,锁定仅在重复坏行为时使用。
如何在不盲目猜测的情况下选择实用的限制
好的限制以一个目标为起点:在让正常用户完成工作的同时保护后端。第一天不需要完美的数字。你需要一个安全的基线和可调节的机制。
一个简单起点是按 API 密钥设定与 API 类型相匹配的限制:
- 低流量:每密钥每分钟 60–300 次请求
- 中等流量:每密钥每分钟 600–1,500 次请求
- 高流量:每密钥每分钟 3,000–10,000 次请求
然后按端点类型拆分限制。读取通常更便宜,可以设置更高的限额。写操作会改变数据,往往触发额外逻辑,应设更严格的上限。常见模式例如 GET 路由 1,000/分钟,而 POST/PUT/DELETE 为 100–300/分钟。
还要识别昂贵端点并单独处理。搜索、报表生成、导出、文件上传以及任何触及多张表或运行重业务逻辑的操作,都应有更小的桶,即便其余 API 很宽松。如果你的后端使用可视化工作流(例如 Business Process 流程),每增加一步都会在负载下放大工作量。
用两个窗口来处理突发:短窗口吸收快速峰值,长窗口控制持续使用。常见组合是 10 秒加 10 分钟。这既能容忍快速点击的真实用户,又不会给爬虫无限制速度。
最后,决定客户端超限时发生什么。大多数公共 API 返回 HTTP 429 并给出明确的重试时间。如果工作可以安全延迟(如导出),考虑排队而不是硬阻断,这样真实用户仍能拿到结果。
设计让人感觉公平的按键配额
按键配额通常是最公平的方式,因为它与客户实际使用服务的方式一致:一个账号、一把 API 密钥、责任明确。基于 IP 的限制仍有用,但常常惩罚无辜用户。
共享 IP 是最大的问题来源。整个办公室可能走同一个公网 IP,移动运营商可能把成千上万台设备放在小池子后面。如果你只依赖按 IP 的上限,一个吵闹的用户会拖慢所有人。按密钥的配额避免了这一点,同时可以保留轻量的按 IP 限制作为明显洪水的后备。
为了让配额显得公平,把它们与客户等级绑定,同时不要困住新用户。免费或试用密钥应能用于真实测试,但不能达到破坏你的规模。简单做法是允许慷慨的突发、中等的持续速率和匹配计划的每日配额。
一个保持可预测的按密钥策略:
- 允许短暂突发(页面加载、批量导入),然后执行稳定速率。
- 为每个密钥加每日上限以限制爬取和失控循环。
- 按计划提高限额,但保持相同结构以保持行为一致。
- 对新创建的密钥使用较低上限,直到它们建立良好记录。
- 保留小的按 IP 上限以捕获明显的洪水和配置错误的客户端。
为阻止密钥共享和自动注册,你不需要重度监控。先用简单检查:异常地理位置变化、单个密钥每小时太多不同 IP、或同一来源创建太多新密钥。先标记并放慢速度;只有在重复信号出现时才锁定。
匿名流量更适合更严格的上限。如果你提供试用密钥,对其进行严格限流并在提高限额前要求基本验证。如果你的 API 支持公共表单,考虑为匿名流量提供独立端点和配额,以保护其余后端。
如果你用 AppMaster 构建 API,按密钥的逻辑更容易保持一致,因为认证、业务规则和响应处理都在一个地方。
对客户端友好的响应和头(便于恢复)
长期来看,速率限制只有在客户端能理解发生了什么并知道下一步该做什么时才有效。目标是让响应乏味而可预测:相同状态码、相同字段、在所有端点间含义一致。
当客户端触及限制时,返回 HTTP 429(Too Many Requests)并提供清晰信息与具体等待时间。最快的改进是添加 Retry-After,因为即便是简单客户端也能正确暂停。
一组简短的头信息可以让限流变得自说明。在成功响应和 429 响应中都包含它们,以便客户端自我节奏和恢复:
Retry-After:重试前应等待的秒数X-RateLimit-Limit:当前窗口允许的请求数X-RateLimit-Remaining:当前窗口剩余请求数X-RateLimit-Reset:窗口何时重置(Epoch 秒或 ISO 时间)X-RateLimit-Policy:类似“60 requests per 60s”的短文本
让错误体结构化,像成功响应一样稳定。一个常见模式是包含稳定的 code、易读的 message 和恢复提示的错误对象。
{
"error": {
"code": "rate_limit_exceeded",
"message": "Too many requests. Please retry after 12 seconds.",
"retry_after_seconds": 12,
"limit": 60,
"remaining": 0,
"reset_at": "2026-01-25T12:34:56Z"
}
}
告诉客户端在看到 429 时如何退避。指数退避是一个不错的默认:等待 1s,接着 2s,再 4s,并设置上限(例如在 30–60 秒)。同时明确何时停止重试。
在接近配额时避免惊喜。当密钥接近上限(例如使用 80–90%)时,在响应体或头里包含警告字段或提示,让客户端在开始失败前放慢速度。这在一个脚本能快速命中过多个路由并比预期更快耗尽预算时尤为重要。
逐步推进:限制与配额的简单发布计划
把限制视为产品行为而不是一次性的防火墙规则,发布效果更好。目标始终相同:在让正常客户继续工作的同时保护后端。
从快速清单开始。列出每个端点,并按成本(CPU、数据库、第三方调用)和风险(登录、密码重置、搜索、文件上传)标记,这能防止你把一刀切的限制应用到所有地方。
通常能避免惊喜的发布顺序:
- 按成本和风险给端点打标签,决定哪些需要更严格的规则(登录、批量导出)。
- 按优先顺序选择身份标识:先 API 密钥,再用户 ID,IP 作为回退。
- 添加短窗口限制(每 10 秒或每分钟)以阻止突发和脚本。
- 添加长窗口配额(每小时或每日)以限制持续使用。
- 为可信系统和内部工具添加放行列表,确保运维不被拦阻。
首次发布保持谨慎比较好。放宽比解封更容易。
监控并调优,然后为你的策略做版本管理。跟踪触发限制的请求数量、哪些端点触发、受影响的独立密钥数量。当你更改数值时,把它当作 API 变更:记录文档、逐步发布,并保持新旧规则分离以便快速回滚。
如果你用 AppMaster 构建 API,把这些规则和端点与业务逻辑一起规划,这样限制能匹配每个工作流的真实成本。
能阻止滥用但不过分激进的锁定工作流
锁定像安全带。它们应在迅速阻止明显滥用的同时,让正常用户在出错时有明确的恢复路径。
平和的做法是渐进式惩罚。假设客户端可能是配置错误而非恶意,只有在模式重复时才升级处罚。
一个简单的渐进阶梯
使用一组小而清晰的步骤,既容易说明也便于实现:
- 警告:告知客户端他们接近限制,并说明何时重置。
- 降速:对该密钥增加短延迟或收紧每秒限制。
- 临时锁定:封禁数分钟(不是数小时),并给出精确解封时间。
- 更长锁定:只有在跨多个窗口反复突发后才采取。
- 人工审核:针对看起来有意或持续出现的模式。
选择锁定对象很重要。按 API 密钥通常最公平,因为它针对调用方,而不是共享网络中的所有人。按账号有助于用户轮换密钥时处理。按 IP 对匿名流量有用,但会导致对 NAT、办公室和移动运营商的误判。当滥用严重时,结合多种信号(例如锁定该密钥并对该 IP 要求额外检查),但尽量把影响范围做小。
把锁定设为基于时间并使用简单规则:“被封禁到 14:05 UTC”以及“在 30 分钟良好行为后重置”。避免对自动化系统做永久封禁。错误的客户端可能会循环并快速耗尽限额,所以设计随时间递减的惩罚。持续的低速期应降低惩罚级别。
如果你在 AppMaster 中构建 API,这个阶梯很适合用计数器加 Business Process 来实现:判定允许、降速或阻断,并为密钥写入解锁时间。
对于重复违规者,保留人工审核通道。不要与用户争论。请求他们提供请求 ID、时间戳和 API 密钥名,然后基于证据做决定。
导致误判的常见错误
误判是指你的防护阻挡了正常用户。通常发生在规则对人们实际使用 API 的方式过于简单时。
典型错误是对所有东西使用一个全局上限。如果你把廉价读取端点和昂贵导出一视同仁,要么对廉价端点过度保护(令人恼火),要么对昂贵端点保护不足(危险)。按端点成本拆分限制,并对重负载路径更严格。
仅按 IP 限制是另一个陷阱。很多真实用户共享一个公网 IP(办公室、学校、移动运营商)。一个重度用户会导致所有人被封,看起来像随机宕机。优先使用按 API 密钥的限制,然后把 IP 作为二级信号用于明显滥用。
故障也会制造误判。如果你的限流存储服务宕机,“关闭失败(fail closed)”会把整个 API 制服。“打开失败(fail open)”则可能引来冲击并导致后端崩溃。选一个明确的回退方案:在边缘保持小的紧急上限,并在非关键端点上优雅降级。
客户端处理比大多数团队预期的更重要。如果你返回泛泛的 429 而没有清晰信息,用户会更频繁地重试并触发更多封禁。务必发送 Retry-After,并保持错误文本具体(“该密钥请求过多。请 30 秒后重试。”)。
最容易避免的问题是保密。隐藏的限制在客户第一次遇到生产负载时会像 bug。公开简明策略并保持稳定。
避免误判的快速清单:
- 为昂贵与廉价端点分开限制
- 首选按 API 密钥限制,而不是仅按 IP
- 定义当限流器不可用时的行为
- 返回带
Retry-After的清晰 429 响应 - 在强制执行前记录并告知限制策略
如果你用 AppMaster 构建 API,通常意味着为每个端点设置不同上限并返回一致的错误载荷,让客户端无需猜测即可退避。
真正有用的监控与告警
速率限制只有在你能实时看到发生的事情时才有用。目标不是捕捉每一次峰值,而是发现会变成宕机或惹怒用户的模式。
从一小组能解释流量与意图的指标开始:
- 每分钟请求数(总体与按 API 密钥分)
- 429 率(被限请求)与 5xx 率(后端压力)
- 重复的 401/403 激增(错误密钥、凭证填充、配置错误的客户端)
- 按量与成本排序的热门端点(慢查询、重导出)
- 新出现或意外进入前十的端点
为将“坏流量”与“我们刚发布了东西”区分开,给仪表板加些上下文:部署时间、功能开关变化、营销推送。如果流量在发布后暴增且 429/5xx 比例健康,通常是增长而非滥用。如果暴增集中在某个密钥、某个 IP 段或某个昂贵端点,则应怀疑滥用。
告警要乏味一些。使用阈值加冷却时间,避免每分钟被同一事件反复叫醒:
- 429 率超过 X% 持续 10 分钟,通知但每小时只通知一次
- 5xx 超过 Y% 持续 5 分钟,立即告警
- 单个密钥超过配额 Z% 持续 15 分钟,开启调查
- 401/403 在 N/min 以上激增,标记可能滥用
当告警触发时,写一条简短的事件笔记:发生了什么变化、你看到的内容(热门密钥/端点)、以及你调整了什么(限制、缓存、临时封禁)。随着时间推移,这些笔记会成为真正的操作手册。
示例:你发布了新的搜索端点,流量翻倍。如果大多数调用集中在该端点并分布在许多密钥上,稍微提高每密钥配额并优化端点。如果是某一密钥不断触发导出并导致延迟上升,则单独限制该端点并联系该密钥所有者。
发布前后要做的快速自检清单
系统正常工作时应该平淡无奇。这个清单能捕捉通常导致误判或留下明显漏洞的问题。
在发布新端点前
在预发布和发布后立即运行这些检查:
- 身份:确认限流按正确的标识(优先 API 密钥,其次用户或 IP)生效,且轮换密钥不会继承旧惩罚。
- 限制:设置默认按密钥配额,然后基于端点成本(廉价读取 vs 昂贵写入)与预期突发调整。
- 响应:返回清晰的状态与恢复信息(重试时间、剩余配额、稳定的错误码)。
- 日志:记录被限制的对象(密钥/用户/IP)、路由、触发规则和用于支持的请求 ID。
- 绕过:为你的监控与可信集成保留应急放行列表。
如果你在 AppMaster 上构建,每个新 API 端点都应视为一次成本分层决策:简单查找可慷慨,任何触发大量业务逻辑的操作应起始更严格。
发生事件时(滥用或突发流量)
在保护后端的同时让真实用户恢复:
- 仅临时提高风险最低路由的上限(通常是读取)并观察错误率。
- 在调查时为已知良好客户添加短期放行名单。
- 对特定风险路由收紧规则,而不是降低全局上限。
- 启用更严格的身份(要求 API 密钥,减少对 IP 的依赖)以避免封堵共享网络。
- 捕获样本:热门密钥、热门 IP、User-Agent 及精确的负载模式。
在为客户提高限额前,检查他们的正常请求模式、端点构成以及他们是否能合并请求或增加退避。同时确认他们没有在多个应用间共享一个密钥。
每月复盘:受限最多的端点、受到限流的流量占比、新的高成本路由,以及你的配额是否仍与真实使用匹配。
示例场景:在不破坏用户的情况下保护真实的公共 API
假设你运行一个公共 API,被两个应用使用:一个客户门户(高流量、稳定)和一个内部管理工具(低流量但权限强)。两者都使用 API 密钥,门户还有用户登录端点。
某天下午,一个合作方发布了有缺陷的集成。它开始在单一 API 密钥上以每秒 200 次的速率重试失败请求。没有保护的话,这把密钥会挤占所有其他用户的容量。
按密钥限制能限制影响范围。出问题的密钥触达每分钟上限,收到 429 响应,其他客户继续工作。你可能还对昂贵端点(如导出)设置更低的独立限制,这样即使流量“被允许”,也无法压垮数据库。
同时,暴力破解登录攻击开始猛击认证端点。与其阻断整个 IP 范围(会影响 NAT 后的真实用户),你可以先降速然后基于行为锁定:对每个账号过多失败尝试再加上短窗口内的按 IP 检测。攻击者会经历渐长的等待,然后是临时锁定。
真实客户如果多次输错密码也能恢复,因为你的响应是清晰且可预测的:
- 返回带有
Retry-After的 429,让客户端知道何时重试 - 短暂锁定窗口(例如 10–15 分钟),而不是永久封禁
- 一致的错误信息不泄露账号是否存在
为确认修复,你监控几个指标:
- 按密钥与端点的 429 率
- 认证失败率与锁定计数
- P95 延迟和事件期间的数据库 CPU
- 受影响的独立密钥数量(应当很少)
这就是保护性速率限制在不惩罚真实用户情况下保护后端的样子。
下一步:先放一个小策略并迭代
第 1 天不需要完美模型。先放一个小且清晰的策略,随着学习真实用户行为逐步改进。
一个稳健的第一版通常包含三部分:
- 一个覆盖大多数端点的按密钥基线(每分钟请求数)
- 对昂贵端点(搜索、导出、文件上传、复杂报表)更严格的上限
- 带短消息的清晰 429 响应,告诉客户端下一步该做什么
仅在滥用风险高且意图容易推断时添加锁定。注册、登录、密码重置和令牌创建是典型候选。初期把锁定时间保持短(分钟级而非天级),优先采用渐进摩擦:先降速、然后临时封禁、再要求更强校验。
把策略用白话写下来,这样支持团队在不用开发参与的情况下也能解释清楚。包含被限制对象(按 API 密钥、按 IP、按账号)、重置窗口和客户如何恢复。
如果你在构建新后端时实现这些,AppMaster 可能是实用的选择:你可以可视化创建 API、定义业务工作流(包括计数器和锁定决策),然后部署到云或在需要完全控制时导出生成的源代码。


