什么是速率限制器?算法、配额与作用范围

什么是速率限制器?算法、配额与作用范围

Scrapeless Web Unlocker 处理基于 URL 的内容获取,而你的应用程序可以在其所允许的请求外部放置一个速率限制器。

摘要

  • 速率限制器根据一项策略做出是否允许的接入决策。 它的作用范围和计数单元决定了限流实际在保护什么。
  • 不同算法允许不同的突发模式。 相同的平均限制在窗口边界处可能产生不同的流量。
  • 分布式工作节点需要协调记账。 独立的本地计数器不能强制执行一个精确的全局额度。
  • 仅按请求次数计数无法约束所有资源成本。 根据需要用大小、复杂度、并发度和支出控制来保护高成本操作。

速率限制器控制对某个操作的接入

速率限制器是一个组件,它根据关于一段时间内活动的策略来决定某个操作能否继续。它可以位于客户端,在请求发送之前;位于 API 网关;或位于应用程序内部靠近高成本操作的地方。该组件观察相关状态并做出接入决策,而策略定义要为谁、按什么来计数。

一个有用的策略会指明主体、操作、计数单元、时间模型以及用尽后的动作。例如,一个假设的导出服务可能为租户分配一个导出启动额度,并为活动导出分配另一个限制。这是一个示例性设计,而不是 Scrapeless 的配额。缺少这些细节时,类似 requests per minute 的表述会掩盖在高负载下最重要的行为。

《 HTTP 429 定义 》为 HTTP 服务提供了一个针对过多请求活动的状态码,但该状态码并未规定一个通用的限流算法。服务器可以根据自己的策略识别调用方并对操作计数。观察到 429 的客户端无法推断服务是使用固定窗口、令牌桶,还是更复杂的资源预算。

作用范围决定谁共享同一额度

限制器的作用范围决定哪些请求在同一容量上竞争。服务可以按账户、租户、API 密钥、用户、路由、IP 地址或组合键来计数活动。基于 IP 的策略可以把处于同一网络后的不相关用户归为一组,而基于账户的策略可以合并来自许多不同进程的流量。应选择与服务需要保护的资源或公平性边界相匹配的作用范围。

分层策略可以同时生效。一个请求可能需要在租户额度、端点额度以及全服务上限之下都有可用容量。接入系统必须定义这些检查如何交互以及被接受的工作如何记账。一组松散独立的检查可能导致扣减不一致,或者在另一项约束本应阻止时仍然接纳工作。

客户端应用程序同样需要这种作用范围意识。如果多个采集器使用同一个服务提供商账户,它们的调度决策应共享该账户的配额,而不是各自声称拥有完整额度。本地限制器仍然可以保护单个进程,但除非其协调机制覆盖每一个相关消费者,否则不应被描述为精确的全局策略。

固定窗口和滑动窗口以不同方式计算时间

固定窗口限制器在命名的时间区间内对被接纳的操作计数,并在边界时重置计数。这种方法易于描述且运行成本可能很低。它的边界行为很重要:客户端可以在一个区间接近末尾时耗尽该区间的额度,并在下一个区间一开始立刻消耗下一段额度。因此,分开的区间上的较低平均值可能包含一次集中的突发。

滑动日志限制器为移动区间内的活动保留时间戳,并直接评估当前窗口。它可以描述更紧的滚动策略,但存储每个操作的时间戳具有状态成本。滑动窗口计数器通过聚合计数来近似这种行为。它的精度和边界行为取决于所选算法,因此应记录策略是精确还是近似的。

在测试这些设计时,应在区间边界使用合成流量。稳定的工作负载可能永远不会暴露边界突发或与时钟相关的不一致。应在运行测试前先定义预期的接纳情况,然后将被接纳的操作与策略对比,而不是仅仅统计错误响应。限制器的正确性是其在给定模型下决策历史的属性。

令牌桶将持续速率与突发容量分离

令牌桶维护一个随时间填充、直到最大容量的额度。被接纳的操作按照其指定成本消耗令牌。填充速率描述可持续的活动,而桶容量描述可在一次突发中花费的累积额度。这是两个独立设置,应分别向客户端解释。

一个假设的令牌桶可以在一段空闲期后允许短暂突发,同时仍然约束长期活动。这种行为可能适合交互式流量,但对无法吸收突发的后端来说可能不合适。应根据服务实际的处理承受能力来选择容量,而不是仅仅因为它匹配某个期望平均速率就照搬默认值。

《 rate-limiting algorithm overview 》描述了令牌桶和漏桶的概念。漏桶术语可以指代不同的监管或整形设计,因此应说明你的实现是拒绝多余操作,还是将其排队以按受控泄放速率处理。当两个库使用相同名称却具有不同运行行为时,实现名称本身是不足够的。

设计有用属性需要记录的边界
固定窗口简单的区间记账跨相邻区间的突发活动
滑动日志直接滚动窗口历史每次操作的状态与处理成本
滑动计数器聚合滚动近似近似误差与区间加权
令牌桶区分持续速率与突发额度补充速率、容量与操作成本
基于队列的整形受控的调度节奏队列容量、等待时间与过期

分布式记账需要原子决策

分布式限流器必须协调其检查与更新,使并发调用方无法同时花掉同一剩余容量。先读取计数器再稍后更新,在多个工作进程观察到旧值时会产生竞争条件。应使用原子操作或其他适合状态存储和一致性要求的协调机制。具体实现取决于所选基础设施。

协调本身也有成本。集中式决策点可以简化严格的全局配额,但会增加网络延迟和依赖。独立的区域配额可以减少协调需求,但需要明确的分配和超量模型。要说明设计实际提供的保证。近似的分布式控制可能有用,但在没有支持证据时,不应被宣称为精确的全局上限。

时间处理也需要同样的清晰度。要决定由哪个组件提供用于窗口边界或补充计算的时间、状态如何过期,以及进程重启时会发生什么。测试应覆盖并发更新和状态存储的变化,而不仅是一名工作进程以均匀间隔发起调用。一个在单进程演示中看起来正确的限流器,在一整套服务中可能表现不同。

速率、并发、配额与预算是不同的概念

速率限制约束一段时间内的活动,而并发限制约束当前正在进行的操作。配额可以约束更长期的总量,财务预算可以约束支出。单一机制不会自动强制执行其他类型的限制。对于慢且昂贵的操作,即使保持在请求速率限制之内,也可能耗尽内存或积累过多在途工作。

请求计数也只是工作量的一种度量。一次大型导出或复杂查询可能比一次小型查找代价更高。 OWASP 资源消耗控制 涵盖负载大小、操作频率、记录数量和服务支出。当资源成本不能用“每个 HTTP 请求一个令牌”充分表示时,应使用这些控制。

HTTP 语义引入了另一个区分:被接受的请求并不总是完成的业务操作。 HTTP 响应语义 将消息结果与应用的处理契约分开。异步导出可能在被接受后,在验证或处理阶段失败。要决定操作在何种阶段消耗各类预算,以及如何对从未产生有用输出的工作进行记账。

资源耗尽与依赖失败需要显式策略

当限流器耗尽时,应为调用方和操作所有者产生清晰的结果。拒绝、有限排队以及放弃未发送的工作会带来不同的产品后果。应根据任务的价值和截止时间选择行为。无界队列会消耗内存,并让用户为当容量可用时已不再相关的工作长时间等待。

当限流器的状态存储不可用时,需要一套明确的依赖策略。在无记账的情况下放行工作可以保护可用性,但会削弱上限控制;阻止工作可以保护预算,却会拒绝有用的请求。不同操作可能需要不同决策。应记录这种权衡,并通过受控故障场景进行测试,而不是让存储库的偶然行为变成实际策略。

错误报告应标识受影响的范围,同时不暴露凭据或其他租户的活动。应包含策略标识符、操作类别以及调用方可据此采取行动的脱敏原因。运维人员需要汇总的准入、拒绝、队列和处理指标。高拒绝计数可能表示滥用、配额过小或客户端缺陷,而这些原因需要不同的应对方式。

关注公平性与有用工作

良好的限流器在执行既定策略的同时保护有用工作。要衡量谁获得了容量、被接受的工作等待了多久,以及昂贵操作是否挤占了普通流量。先到先得的分配方式,可能会让一个租户耗尽共享配额,即便每次单独请求都是合法的。如果公平性是产品需求,就需要显式的分配设计。

测试负载应包括突发流量、不均衡的租户需求、慢操作、大输入以及同时启动的工作进程。将这些测试保留在授权的预发布或本地环境中,使用合成数据并控制规模。目标是验证决策模型,而不是通过压垮生产服务来“摸索”其阈值。应对照预期的范围与时间策略,比较观测到的准入情况。

有用的运维报告会区分已接受请求、已完成操作、已存储记录和实际金融消耗。这些数值出于正当理由可能不同。保持这些区分,可以让团队看清限流器是否在保护真正的资源,以及配额分配是否产生了预期的产品结果。单一的成功百分比无法解释所有这些边界。

将限流器放在 Scrapeless 工作流外围

客户端可以在调用 Scrapeless Web Unlocker之前实施准入控制,而服务自身的账号规则则继续独立生效。 Web Unlocker 概览 描述基于 URL 的内容获取。您的应用程序选择目标范围、排队工作,并决定返回的内容是否满足其数据集标准。本地限流器无法更改目标网站的权限策略。

评审 Scrapeless 定价 了解服务成本以及相关的 并发概念 用于控制活跃工作。对消耗同一账户额度的使用方应用共享配额。将数据源的授权采集条件与服务预算一起保持可见,因为网络容量、财务能力和采集数据的权限是彼此独立的约束。

一个假设的报告任务可以预留有上限的每日配额,限制活跃请求数量,并在报告窗口结束后使未发送的观测结果失效。其完成报告应标识被接受的记录以及未采集的范围。这样的设计把限流器与实际业务需求联系起来,并在可用容量小于需求时,使所得数据集更易于评估。

结论

限流器是一种准入系统,其行为取决于范围、时间模型、算法和记账一致性。根据需要保护的资源选择这些特性,然后用受控流量测试其边界。将速率控制与应用所需的成本和活跃工作限制结合起来,并报告被接纳请求实际产生的有效工作。

构建您的 Web 数据工作流

在共享请求配额内使用 Web Unlocker,并分别控制活跃工作、支出和被接受的内容。

立即注册即可获得 $5 免费额度 — 无需信用卡.

领取您的 $5 额度 →

常见问题

限流器和并发控制器是同一种东西吗?

限流器和并发控制器控制的是不同的量。限流限制的是一段时间内的活动,而并发限制的是同时进行的操作。当快速响应会产生大量启动请求,或慢速响应会产生过多的并发工作时,系统可能需要两者同时存在。

哪种限流算法永远是最好的?

没有哪种限流算法对所有服务都是最好的。应根据所需的突发行为、精度、协调成本、状态规模和公平性模型进行选择。记录这些选择,以便用户和运维人员能够预测策略允许的行为。

每个工作进程都能执行自己的全局配额吗?

独立的工作进程计数器无法在其配额和协调未覆盖整个范围时,强制执行一个精确的全局配额。本地限制对过程控制很有用,但共享账户额度需要共享记账,或显式有界的分区设计。

HTTP 429 能标识使用了哪种限流算法吗?

HTTP 429 并不能标识限流算法。它表明在服务策略下请求活动过多。请阅读文档中的计数范围和错误约定,而不要仅凭状态码就推断是固定时间窗或令牌桶。

每个请求一个令牌是否可以保护所有昂贵的端点?

每个请求一个令牌并不一定能保护所有昂贵的端点。请求成本可能取决于负载大小、返回记录数、处理复杂度或第三方收费。为被保护的资源增加合适的成本、并发、大小和支出控制。

参考资料