速率限制是一种简单但非常有效的技术,用于保护API免遭无意和恶意的过度使用。如果没有速率限制,任何人都可以用请求轰炸服务器并导致吞噬资源的流量高峰,“饿死”其他用户,并使服务无响应。本文介绍了速率限制以及限制到达 API 和服务的请求数量的重要性。我们解释什么是速率限制及其工作原理,并介绍可用于为您的用例采用速率限制的不同类型的算法。
速率限制是限制用户可以对特定 API 或服务发出的请求数量的做法。您可以限制用户在特定时间范围内重复执行某项操作(即尝试登录帐户或发送消息)的频率。如果有人达到他们的限制,服务器将开始拒绝其他请求。速率限制既是网络安全预防措施,也是软件质量保证 (QA)的关键部分。公司使用速率限制来:
从技术上讲,速率限制是流量整形的一种形式。这种做法让您可以控制流量的流动和分配,以防止基础设施过载或出现故障。大多数具有速率限制的系统的上限都远高于即使是高容量用户也可以实际要求的上限。最常见的例子是社交媒体消息传递。所有社交媒体网站都对您可以发送给其他用户的直接消息的数量设置了上限。如果有人决定向其他配置文件发送一千条消息,速率限制就会启动并阻止用户在一段时间内发送消息。
以下列出了为什么速率限制是任何健康服务的重要方面的主要原因:
为了设置速率限制,管理员对用户在特定时间范围内可以向服务器或 API 发出的请求数量设置上限。通常,限速机制跟踪两个关键因素:
速率限制的主要指标是每秒事务数 (TPS)。如果单个 IP 地址在特定时间段内发出过多请求(即超过其 TPS 限制),则速率限制会阻止服务器或 API 响应。用户收到一条错误消息,并且在计时器重置之前无法发送进一步的请求。
速率限制总是依赖于某种形式的节流机制来减慢或阻止请求。管理员在服务器端或客户端实施速率限制,具体取决于哪种策略更适合用例:
许多管理员还根据用户名设置速率限制。这种方法可以防止暴力攻击者尝试从多个 IP 地址登录。
让我们看看可用于控制对服务器或 API 的访问的不同类型的速率限制。请记住,您可以将不同类型组合成一个混合策略。例如,您可以限制基于 IP 地址和特定时间间隔的请求数量。
基于时间的速率限制
基于时间的速率限制在预定义的时间间隔上运行。例如,服务器可以将请求限制为每个时间段的特定数量(例如每分钟 100 个)。基于时间的速率限制通常适用于所有用户。您可以将这些限制设置为固定(计时器倒计时,无论用户何时以及是否提出请求)或滑动(倒计时在有人发出第一个请求时开始)。
地理速率限制
地理速率限制限制来自特定区域的请求数量。在运行基于位置的广告系列时,这些上限是一个很好的选择。管理员可以限制来自目标受众之外的请求并提高目标区域的可用性。
这些速率限制也有助于防止可疑流量。例如,您可以预测某个地区的用户在晚上 11:00 到早上 8:00 之间不太活跃。您为这次设置了较低的速率限制,这进一步限制了任何希望引起恶意流量问题的攻击者。
基于用户的速率限制
基于用户的速率限制控制单个用户在特定时间范围内可以执行的操作数。例如,服务器可能会将每个用户每天可以进行的登录尝试次数限制为 100 次。
基于用户的限制是最常见的速率限制类型。大多数系统跟踪用户的 IP 地址或 API 密钥(或两者)。如果用户超过设定的速率限制,应用程序会拒绝任何进一步的请求,直到每用户计数器重置。请记住,这种类型的速率限制需要系统维护每个用户的使用统计信息。此类设置通常会导致运营开销并增加总体IT 成本。
并发率限制
并发率限制控制系统在特定时间范围内允许的并行会话数。例如,一个应用程序可能会在一分钟内阻止超过 1000 个会话。
服务器速率限制
服务器速率限制可帮助管理员在不同服务器之间分担工作负载。例如,如果您运行一个包含五台服务器的分布式架构,您可以使用速率限制为每台设备设置一个上限。
如果其中一台服务器达到其上限,则设备会将其路由到另一台服务器或丢弃请求。这种策略对于实现高可用性和防止针对特定服务器的 DoS 攻击至关重要。
API 基于端点的速率限制
这些速率限制基于用户尝试访问的特定 API 端点。例如,出于安全或过载考虑,管理员可能会将对特定端点的请求限制为每分钟 50 个。
速率限制算法
以下是公司实施速率限制所依赖的最常见算法:
以下是实施速率限制的分步指南(尽管设置限制的确切方式取决于您的特定技术栈):
对于大多数用例来说,实施速率限制是一个简单的过程。例如,如果您使用 Nginx 作为 Web 服务器并希望在服务器级别设置速率限制,您将使用 ngx_http_limit_req_module模块。只需将以下代码添加到 Nginx 配置文件中,即可根据用户的 IP 地址设置速率限制:
HTTP { limit_req_zone $binary_remote_addr zone=one:10m rate=2r/s; ... 服务器 { ... 位置/促销/ { limit_req zone=one burst=5; } }
上面的代码平均每秒允许不超过 2 个请求,而突发不能超过 5 个请求。
速率限制对于 API、应用程序和网站的安全性和质量至关重要。未能限制请求数量会使您容易受到基于流量的攻击并导致性能不佳(这会导致更高的跳出率、客户保留问题等)。考虑到实施此预防措施有多么容易,对于大多数用例来说,设置速率限制是一个无需动脑筋的决定。