【问题标题】:API Traffic Shaping/Throttling Strategies For Tenant Isolation用于租户隔离的 API 流量整形/节流策略
【发布时间】:2018-12-10 03:50:42
【问题描述】:

我将通过提供一些关于我们正在做什么以及我们面临的问题的背景来开始我的问题。

  • 我们目前正在构建一个 SaaS(托管在 Amazon AWS 上),它由位于 API 网关后面的多个微服务组成(我们使用的是 Kong)。
  • 网关处理身份验证(通过具有 API 密钥的消费者)并公开我提到的这些微服务的 API,所有这些都是无状态的(没有会话、cookie 或类似内容)。
  • 每项服务都使用 ECS 服务(在一台或多台 EC2 机器上运行的每个服务一个或多个 docker 容器)进行部署,并使用 Amazon Application Load Balancer (ALB) 进行负载平衡。
  • 所有租户(客户端)共享相同的环境,即相同的机器和资源。鉴于我们的商业模式,我们预计(起初)只有少数但“大”的租户。
  • 大多数对这些服务的请求在请求期间转换为大量资源使用(主要是 CPU)。服务一个请求所需的时间在 2-10 秒的范围内(而不是像传统的“类 web”应用程序那样毫秒)。这意味着我们每分钟处理的请求相对较少,其中每个请求都需要一段时间来处理(后台或批处理不是一种选择)。

目前,我们没有策略来限制或限制租户在给定时间段内可以发出的请求数量。考虑到上面的最后两个考虑因素,很容易看出这是一个问题,因为租户发出的请求超出我们的处理能力几乎是微不足道的,这会导致服务质量下降(即使对于其他租户来说也是如此,因为共享资源方法)。

我们正在考虑限制/节流或一般准备系统以“隔离”租户的策略,因此一个租户不能通过发出超出我们处理能力的请求而降低其他租户的性能:

  • 速率限制:定义租户可以发出的最大请求数/m。如果有更多请求到达,请丢弃它们。 Kong甚至有一个插件。遗憾的是,我们使用“按请求付费”的定价模式,而业务不允许我们使用这种策略,因为我们希望为尽可能多的请求提供服务以便获得报酬。如果租户的请求过多,则需要更多时间。
  • 租户隔离:为每个租户创建一个隔离的环境。这个也被丢弃了,因为它使维护更加困难,并导致资源使用率降低和成本增加。
  • 自动缩放:调出更多机器来吸收爆发。根据我们的经验,Amazon ECS 在这方面的速度不是很快,等到这些新机器准备就绪时可能为时已晚。
  • 请求“节流”:在 API 网关级别使用 Leaky Bucket 或 Token Bucket 等算法,以确保请求以我们知道可以处理的速度到达服务。

目前,我们倾向于采用选项 4。我们希望以这样一种方式实施请求限制(流量整形),以使在与租户预先商定的费率内(由合同强制执行)提出的所有请求都将通过沿着服务毫不拖延。由于我们事先知道每个租户每分钟将发出多少请求(至少估计),我们可以相应地调整我们的基础设施(加上安全边际)。

如果突发到达,多余的请求将被排队(达到一个限制),然后以固定速率释放(使用漏桶或类似算法)。这将确保租户不会影响其他租户的性能,因为请求将以预定义的速率访问服务。理想情况下,允许的请求率将是“动态的”,租户可以使用其他未使用它们的租户的“每分钟请求数”(在安全范围内)。我相信这被称为“动态速率漏桶”算法。目标是最大限度地利用资源。

我的问题是:

  • 建议的策略是否可行?您知道此用例的任何其他可行策略吗?
  • 是否有可以提供这种流量整形功能的开源、商业或 SaaS 服务? 据我所知 Kong 或 Tyk 不支持这样的东西,所以......还有其他 API网关呢?
  • 如果 Kong 不支持这一点,实现我所说的插件有多难?我们必须考虑到它需要一些共享状态(例如使用 Redis ) 因为我们使用了多个 Kong 实例(用于负载平衡和高可用性)。

非常感谢, 米克尔。

【问题讨论】:

    标签: api throttling rate-limiting trafficshaping


    【解决方案1】:

    在网关端管理请求队列确实是一件棘手的事情,而在这个网关中没有实现它的主要原因可能是它真的很难做到正确。您需要处理所有分布式系统案例,此外,它很难使其“安全”,因为“慢”客户端会快速消耗机器资源。

    这种模式通常被卸载到客户端库,因此当客户端达到速率限制状态代码时,它会使用类似指数退避技术来重试请求。它更容易扩展和实施。

    不能说 Kong,但在这种情况下,Tyk 提供了两个您可以控制的基本数字,配额 - 客户端在给定时间段内可以发出的最大请求数,以及速率限制 - 安全保护。您可以为每个“策略”设置速率限制 1),例如针对一组消费者(例如,如果您有多个服务层,具有不同的允许使用/速率限制),2) 每个单独的密钥 3) 全局用于 API(有效连同关键速率限制)。因此,例如,您可以设置一些适度的客户端速率限制,并使用全局 API 设置来限制总限制。

    如果您想要完全动态的方案,并根据集群负载重新计算限制,应该可以。您将需要在某处编写和运行此调度程序,它会不时根据当前的总使用量(Tyk 为您计算,您从 Redis 获取)执行重新计算,并将通过迭代与 Tyk API 对话通过所有键(或策略)并动态更新其速率限制。

    希望它有意义:)

    【讨论】:

      猜你喜欢
      • 2022-11-17
      • 2019-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 2021-10-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多