云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

腾讯云_数据库应用课程设计_0元

小七 141 0

使用速率限制器扩展API

可用性和可靠性对于所有web应用程序和api来说都是至关重要的。如果您正在提供一个API,那么很可能已经遇到了流量突然增加的情况,这会影响服务质量,甚至可能导致所有用户的服务中断。在最初几次出现这种情况时,您可以在基础设施中增加更多容量,以适应用户的增长。然而,当您运行一个生产API时,您不仅需要使用诸如幂等技术使其健壮,还需要针对规模进行构建,并确保一个坏角色不会意外或故意影响其可用性。在以下情况下,速率限制有助于提高API的可靠性:你的一个用户负责流量的激增,而你需要为其他人熬夜。您的一个用户有一个行为异常的脚本,它意外地向您发送了许多请求。或者,更糟糕的是,您的某个用户故意试图让您的服务器不堪重负。一个用户向你发送了很多低优先级的请求,你要确保它不会影响你的高优先级流量。例如,用户发送大量分析数据请求可能会影响其他用户的关键事务。你的系统内部出了问题,结果你不能提供所有的常规流量,需要丢弃低优先级的请求。在Stripe,我们发现小心地实现一些速率限制策略有助于保持API对每个人都可用。在这篇文章中,我们将详细解释我们认为最有用的速率限制策略,如何将一些API请求优先于其他请求,以及如何在不影响现有用户工作流的情况下安全地使用速率限制器。速率限制器和卸荷装置速率限制器用于控制网络上发送或接收的流量速率。你应该什么时候使用限速器?如果用户能够在不影响请求结果的情况下更改访问API端点的速度,则速率限制器是合适的。如果不能选择隔离他们的请求(通常用于实时事件),那么您将需要在本文范围之外的另一种策略(大多数情况下,您只需要更多的基础设施容量)。我们的用户可以提出很多请求:例如,批量处理付款会导致API上持续的流量。我们发现,客户总是可以(除非一些极为罕见的情况)分散他们的请求多一点,而不受我们的费率限制的影响。速率限制器对于日常操作来说是惊人的,但是在发生事件时(例如,如果服务的运行速度比平时慢),我们有时需要丢弃低优先级的请求,以确保更多的关键请求通过。这叫做甩负荷。这种情况很少发生,但它是保持条纹可用性的一个重要部分。负载卸载程序根据系统的整个状态而不是发出请求的用户来做出决定。卸料机可以帮助您处理紧急情况,因为它们可以让您的业务核心部分在其他部分着火的情况下继续工作。协同使用不同类型的速率限制器一旦知道速率限制器可以提高API的可靠性,就应该决定哪些类型最相关。在Stripe,我们生产4种不同类型的限制器。第一个,请求速率限制器,是迄今为止最重要的一个。如果您想提高API的健壮性,我们建议您从这里开始。请求速率限制器此速率限制器将每个用户每秒的请求限制为N个。请求速率限制器是大多数api可以用来有效管理高流量的第一个工具。我们的请求速率限制经常被触发。仅在这个月,它就拒绝了数以百万计的请求,尤其是对于测试模式的请求,用户无意中运行了一个失控的脚本。我们的API在测试模式和实时模式中提供相同的速率限制行为。这有助于获得良好的开发体验:在从开发转到生产时,脚本不会因为特定的速率限制而遇到副作用。在分析了我们的流量模式之后,我们添加了在实时事件(例如,一次闪电销售)中,短暂突破上限的能力请求速率限制器限制用户每秒的最大请求数。并发请求限制器这个速率限制器不是说"你每秒可以使用我们的API 1000次",而是说"一次只能有20个API请求在进行中"。有些端点比其他端点资源密集得多,用户常常在等待端点返回然后重试时感到沮丧。这些重试会给已经过载的资源增加更多的需求,从而使速度更慢。并发速率限制器很好地解决了这个问题。我们的并发请求限制器触发的频率要低得多(本月有12000个请求),这有助于我们控制CPU密集型API端点。在我们开始使用并发请求限制器之前,我们经常处理由于用户一次发出太多请求而导致的最昂贵端点上的资源争用。并发请求限制器完全解决了这个问题。这是完全合理的调整这个限制器,使它拒绝比请求速率限制器更频繁。它要求您的用户使用不同的编程模型"Fork off X jobs and have them process the queue",而"Hammer the API and back off when I get a http429"。有些API更适合这两种模式中的一种,所以可以随意使用哪一种最适合API的用户。并发请求限制器管理CPU密集型API端点的资源争用。车队使用负荷减载使用这种类型的负载分配可以确保您的车队的一定百分比始终可用于您最重要的API请求。我们将流量分为两种类型:关键API方法(例如创建费用)和非关键方法(例如列出费用)。我们有一个Redis集群,用于计算每种类型的请求数量。我们总是保留一小部分基础设施以满足关键需求。如果我们的预订号是20%,那么超过80%分配的任何非关键请求都将被拒绝,状态代码为503。我们在这个月为一小部分请求触发了这个负载转移。就其本身而言,这并不是什么大问题,我们肯定有能力处理这些额外的请求。但在其他几个月里,这已经避免了停电。车队使用负载卸载为关键请求保留车队资源。工人利用负荷减载器大多数API服务使用一组工人以并行方式独立地响应传入的请求。这个卸料机是最后的防线。如果您的工作人员开始使用请求进行备份,那么这将减少优先级较低的流量。这种情况很少发生,只有在重大事件中才会触发。我们将流量分为4类:关键方法帖子得到测试模式流量我们随时跟踪可用产能的工人数量。如果一个盒子太忙而无法处理它的请求量,它将从测试模式流量开始,慢慢地开始释放不太重要的请求。如果脱落测试模式的流量使它恢复到一个好的状态,那太好了!我们可以开始慢慢恢复交通。否则,它会升级并开始减少更多的流量。很重要的一点是,卸载和带来负载的过程要缓慢进行,否则您可能会最终失败("我摆脱了testmode流量!一切都很好!我带回来了!一切都糟透了!")。我们使用了大量的尝试和错误来调整我们的流量减少率,并确定了一个在几分钟内减少大量流量的速率。这个月,这个速率限制器只拒绝了100个请求,但在过去,当我们遇到负载问题时,它帮助我们更快地恢复。这种卸荷装置限制了已经发生的事故的影响,并提供了损害控制,而前三个更具预防性。Worker utilization load Shedder为关键请求保留工作人员。建筑限价的实践现在我们已经概述了我们使用的四种基本类型的速率限制器以及它们的用途,让我们来讨论它们的实现。有什么速率限制算法?你在实践中是如何实现它们的?我们使用令牌桶算法来进行速率限制。这个算法有一个集中的bucket主机,您可以在每个请求上获取令牌,然后慢慢地将更多令牌滴入bucket中。如果bucket为空,则拒绝请求。在我们的例子中,每个条带用户都有一个bucket,每次他们提出请求时,我们都会从这个bucket中删除一个token。我们使用Redis实现我们的速率限制器。您既可以自己操作Redis实例,也可以使用像ElastiCache这样的托管服务(如果您使用amazonweb服务)。在实施速率限制器时,需要考虑以下重要事项:将速率限制器安全地连接到中间件堆栈中。确保如果速率限制代码中有错误(或者Redis关闭),请求不会受到影响。这意味着在所有级别上捕捉异常,这样任何编码或操作错误都将失败打开,API仍然可以正常工作。向用户显示明确的例外。找出要向用户显示的异常类型。在实践中,您应该根据具体情况决定是使用HTTP429(请求太多)还是HTTP503(服务不可用),以及什么是最准确的。您返回的消息也应该是可操作的。建立安全措施,这样你就可以关闭限制器。确保你有关闭开关,以禁用速率限制器,如果他们踢错了。如果你需要一个人类逃生阀的话,在适当的地方设置功能标志真的很有帮助。设置警报和指标,以了解它们触发的频率。黑暗启动每一个限速器来观察他们的交通