租户隔离的API流量整形/限制策略

时间:2018-07-01 22:06:54

标签: api throttling rate-limiting trafficshaping

我将通过提供一些有关我们正在做的事情和我们面临的问题的上下文来开始我的问题。

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

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

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

  • 费率限制:定义租户可以发出的最大请求数/月。如果有更多请求到达,则将其删除。 Kong甚至有一个插件。可悲的是,我们使用“按请求付费”定价模型,并且业务不允许我们使用此策略,因为我们希望尽可能多地处理请求以获取报酬。如果多余的请求花费更多时间来租客,那就没事了。
  • 租户隔离:为每个租户创建一个隔离的环境。该产品也已被丢弃,因为它使维护工作变得更加困难,并导致资源使用率降低和成本增加。
  • 自动缩放:带来更多机器来吸收突发。根据我们的经验,Amazon ECS不能很快完成此操作,而当这些新机器准备就绪时,可能为时已晚。
  • 请求“节流” :在API网关级别使用诸如Leaky Bucket或Token Bucket之类的算法,以确保请求以我们知道的可处理速率到达服务。

现在,我们倾向于采用选项4。我们希望以某种方式实施请求限制(流量整形),以使在先前与租户商定的价格范围内(通过合同强制执行)的所有请求都可以通过顺畅地提供服务。由于我们提前知道了每个租户每分钟将要发出多少请求(至少被估计),因此我们可以相应地调整基础架构的大小(加上安全裕度)。

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

我的问题是:

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

非常感谢你, 米克尔。

1 个答案:

答案 0 :(得分:2)

在网关端管理请求队列确实是一件棘手的事情,并且可能之所以无法在此网关中实现它,可能是因为这样做确实很难。您需要处理所有分布式系统的情况,此外,很难做到“安全”,因为“慢”的客户端会很快消耗机器资源。

这种模式通常会卸载到客户端库,因此,当客户端达到速率限制状态代码时,它将使用诸如指数回退技术之类的smth重试请求。这是更容易扩展和实施的方法。

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

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

希望有道理:)