了解API速率限制技术

227 阅读5分钟

在Zato中启用速率限制意味着对基于Zato的API的访问可以按终端、用户或服务进行节流--包括使限制仅适用于特定IP地址的选项--如果在选定的时间内超过限制,调用将失败。让我们检查一下如何使用这一切。

限制适用的地点和时间

Rate-limiting aware objects in  Zato

API速率限制在几个层面上起作用,配置总是按照以下顺序检查,从最窄的、最具体的系统部分(端点),到可能适用于多个端点的用户,直到可能被多个端点和用户使用的服务。

  • 首先,每个端点的限制
  • 然后,每个用户的限制
  • 最后,每个服务的限制

当一个请求通过一个端点到达时,会检查该端点的速率限制配置。如果已经达到了呼叫应用程序的IP地址或网络的限制,则拒绝该请求。

接下来,如果有任何与端点相关的用户,则以同样的方式检查该账户的速率限制,同样地,如果达到限制,则拒绝请求。

最后,如果端点的底层服务被配置为这样做,它也会检查其调用限制是否被超过,如果被超过,则相应地拒绝该消息。

请注意,这三个层次是不同的,但它们在允许人们实现的方面是重叠的。

例如,可以在多个端点中使用相同的用户凭证,并表达这样的想法:"允许这个和那个用户每天调用我的API 1000个请求,但无论哪个用户,每个端点最多只能有5个请求/分钟"。

此外,由于可以对服务进行限制,因此可以使其更加灵活,例如:"让这个服务每小时最多调用10000个请求,不管是哪个用户,特定的用户最多可以调用500个请求/分钟,不管是哪个服务,根据什么应用程序调用端点,对REST与SOAP与JSON-RPC端点分别进行限制"。这让人们可以方便地表达在实际情况下经常发生的高级场景。

另外,请注意,API速率限制只适用于REST、SOAP和JSON-RPC端点,它不用于其他API端点,如AMQP、IBM MQ、SAP、任务调度器或任何其他技术。然而,每项服务的限制是有效的,无论服务是用哪个端点调用的,它们都能与WebSockets、ZeroMQ或任何其他端点一起使用。

最后,限制只与传入的请求有关--任何传出的请求,从Zato到外部资源--都不包括在其中。

每个IP的限制

由于每个对象--端点、用户或服务--可以根据调用者的IP地址配置不同的限制,该架构变得更加通用。

这增加了另一个维度,允许表达在基于API的项目中常见的想法,例如。

  • 外部应用程序,根据其IP地址,可以有自己的限制
  • 内部用户,例如使用VPN的公司员工,如果他们的地址在172.x.x.x范围内,可能有雇佣限制
  • 出于性能测试的目的,从几个选定的主机访问Zato可能完全没有限制。

基于IP的限制是机制的一个组成部分,它们不排除每个终端、用户或服务的限制。事实上,对于每个这样的对象,可以独立设置多个IP使用限制,从而允许最高程度的灵活性。

准确的或近似的

速率限制有两种类型。

  • 准确
  • 近似的

精确的速率限制就是这样,精确的--它们使一个限制完全不被超过,甚至不被一个请求超过。

近似限制可能允许极少数的请求超过限制,其好处是近似限制比精确限制检查起来更快。

什么时候使用哪种类型取决于特定的项目。

  • 在一些项目中,呼叫者的限制是1000个请求/分钟还是1005个请求/分钟其实并不重要,因为差别太小,不会产生业务影响。在这种情况下,近似的限制效果最好。

  • 在其他项目中,可能有要求,无论在什么情况下都不能超过限制。在这里使用精确的限制。

Python代码和web-admin

好了,让我们看看如何在Zato网站管理员中定义限制。我们将使用下面的样本服务。

# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

class Sample(Service):
    name = 'api.sample'

    def handle(self):

        # Return a simple string on response
        self.response.payload = 'Hello there!\n'

现在,在web-admin中,我们将配置限制--分别为服务、一个新的和一个新的REST API通道(端点)。

Configuring rate limits for service Configuring rate limits for user Configuring rate limits for user

值得注意的是。

  • 每种类型的对象的配置都是独立的--在同一个调用中,有些限制可能是准确的,有些可能是近似的
  • 每个对象可以有多个配置项
  • 时间单位是 "m"、"h "或 "d",分别取决于限制是每分钟、每小时还是每一天。
  • 同一配置中的所有限制都按其定义的顺序进行检查,这就是为什么最通用的限制应该被列在前面的原因。

测试它

现在,剩下的就是用curl调用服务了。

只要没有达到限制,就会返回一个业务响应。

$ curl http://my.user:password@localhost:11223/api/sample
Hello there!
$

但如果达到了限制,调用者就会收到一个带有429 HTTP状态的错误信息。

$ curl -v http://my.user:password@localhost:11223/api/sample
*   Trying 127.0.0.1...

...

 HTTP/1.1 429 Too Many Requests
 Server: Zato
 X-Zato-CID: b8053d68612d626d338b02

...

{"zato_env":{"result":"ZATO_ERROR","cid":"b8053d68612d626d338b02eb",
 "details":"Error 429 Too Many Requests"}}
$

请注意,调用者永远不知道限制是什么--该信息与其他细节一起保存在Zato服务器日志中,以便API作者可以将调用者得到的东西与阻止他们访问服务的速率限制定义联系起来。

zato.common.rate_limiting.common.RateLimitReached: Max. rate limit of 100/m reached;
from:`10.74.199.53`, network:`*`; last_from:`127.0.0.1;
last_request_time_utc:`2020-11-22T15:30:41.943794;
last_cid:`5f4f1ef65490a23e5c37eda1`; (cid:b8053d68612d626d338b02)

就是这样--我们已经在Zato中创建了一个新的API速率限制定义,并成功地进行了测试!