如何优化API速率限制

优化速率极限

这是一篇对视频的补充博文ShopifyDevs YouTube频道。这是由Shopify Plus的解决方案工程师Zameer Masjedee创建的三篇系列文章的最后一篇。参见第一部分,速率限制简介,第二部分,API速率限制和使用GraphQL,第三部分,在你的应用中实现API速率限制

在这篇文章中,我将继续展示我在本系列第三部分介绍的开发商店中的应用程序中的工作。在你的应用中实现API速率限制。首先,我将教你如何获取对运行应用程序至关重要的速率限制信息。然后,我将指导你如何优化应用程序,以便负责任地使用您的限制。

在本文结束时,您将能够负责任地使用您的费率限制,避免429响应,并构建快速,功能齐全的应用程序。

注意:本文中的所有图像都超链接到YouTube视频的相关时间戳,因此您可以单击它们以获取更多信息。

如何获取速率限制信息

在本节中,我们将介绍如何获取有关速率限制所需的所有必要信息。我们将首先向您展示如何创建您的首字母rawRequest,然后我们将介绍请求中需要包含的各种元素,包括创建初始结构。

创建请求

我们从a开始rawRequest来获取所有的信息。它是这样的:

优化速率限制:GIF显示Zameer演示如何设置原始请求来捕获速率限制信息。

我们会说等待GraphQLClient。rawRequest(产品UpdateMutation, productInput.

制定你的然后条款

我们也要用a然后子句,它允许我们等到执行完成后再执行其他业务逻辑。我们将在下面讨论为什么我们以这种方式构建查询,但是现在,知道您的然后子句应该是这样的:

然后(({错误,数据,扩展,报头,状态}))=> {

}

在这个子句中,我们定义了需要发生的事情,首先记录响应:console.log (JSON。Stringify (data, undefined, 2))。我们想知道的另一件事是我们还有多少API速率限制可用。的日志这个请求看起来是这样的:

console.log (有${extensions.cost.throttleStatus。当前可用}速率限制点可用/n

你完成的,最终的然后子句应该是这样的:

它应该嵌套在等待条款。所以,你的整个rawRequest应该是这样的:

现在,通过我们的扩展,我们可以查看成本,看看我们还有多少可用的速率限制。确保保存所有内容,清空控制台,然后按下运行。

优化速率限制:YouTube教程的截图显示,由于查询10个不同的产品,剩余的958个速率限制点。

您可以看到,当我们发出初始请求时,我们还剩下958个费率限制点,因为我们正在查询10个不同的产品。为了找到终端中的突变,您需要向下滚动到我们从请求中返回的所有数据的正下方。

优化速率限制:YouTube教程的截图,显示Zameer演示了速率限制点的逐渐增加。

它告诉我们从969个速率极限点开始。OB欧宝娱乐APP当我们进行第二次突变时,我们实际上有975个速率极限点。然后又上升了7点,达到982点。

这就是我们的漏桶算法。你可能还记得,我们每秒钟多得50分。我们观察到,在波动的速率限制点上面可用。在我们进行突变,等待响应,打印响应并进行下一次突变所花费的时间中,我们的速率极限在变化。

你可能还喜欢:速率限制简介

回想一下,一个突变只需要10点。这就解释了为什么在不到一秒钟的时间里,我们能够比我们使用它的速度更快地重新填充我们的速率限制。这意味着理论上只要我有生成物,我就可以让这个过程持续下去,而且我不会耗尽所有的速率限制。它不会遇到速率限制错误,如果它能够不断地补充它比它能够消耗它。

这种结构的唯一问题是,虽然你没有浪费你的速率限制,但你也没有优化它。Shopify给你1000个利率限制点-使用它!这就是你如何尽可能高效地运行应用的方法。

“Shopify给你1000个利率限制点——用它吧!”这就是你如何尽可能高效地运营应用的方法。”

通过删除你的等待条款

我们可以做的一件事就是去除等待从我们的rawRequest

在使用Node.js时,等待允许我们发出一个异步请求它有一些未来或者承诺与之相关。这个请求最终会返回一些东西。通过使用等待命令,我们说我们是否要等待它完成。

如果我们选择不使用它,我们的rawRequest可以像迭代一样快速执行循环,在一行中发出多个异步请求。这肯定会更快地消耗你的API速率限制。

我们将在实际操作中看看它,但在此之前,我们需要对我们的rawRequest。为了实现最佳实践,我们将添加一个条款在我们的底部rawRequest因为我们期望出现错误,我们希望记录这个错误。它应该是这样的:

优化速率限制:YouTube教程的截图,展示了如何在原始请求的底部添加catch子句,因为用户期望出现错误,并且用户希望记录该错误。

我们想要改变的另一件事是我们查询的产品的数量。我们不再尝试一次检索10个产品,而是请求一次检索100个产品。

完成这些调整后,您需要保存它,清空终端,然后运行一遍。

达到你的利率上限

在您的终端中应该会发生相当多的更改。您将无法看到整个历史记录,但是您应该看到一些错误,正在发出的一些请求,以及最后剩下的速率限制点。

优化速率限制:YouTube教程的屏幕截图显示,Zameer演示了当您看到许多错误,正在发出一些请求以及剩余的速率限制点时的情况。

很明显,如果我们遇到错误这个方法就不能很好地工作。这不是好的生产级代码。我们需要采取一些保护措施来防止这些错误。

但是,它的作用是将速率限制降低到3。它吃掉了这1000个细胞,这是件好事。它在尽可能多地消耗。但问题是,中国的消费超出了应有的水平。

我们需要找到一种方法来优化它,而不超过我们的速率限制。这就是我们接下来要做的。

通过配对同步和异步请求来优化速率限制

优化速率限制的一种方法是将一系列同步和异步请求配对。每次我们经历我们的循环,我们不想等待每一个请求。这还不够快。我们要等每隔一请求。

这意味着实际上在一秒钟内,或者处理单个请求所需的时间,我们发送了两个请求。因此,我们应该看到我们的速率限制随着时间的推移而降低。

在我们的例子中,我们使用edge参数跟踪这个循环的索引。我们要在上面创建一个条件语句如果声明。优化速率限制:YouTube教程的GIF显示Zameer演示如何通过配对同步和异步请求来优化速率限制。

用一个模函数,我们说如果我们的边缘是偶数还是每隔一个边缘等于(==)零(0),我们想等我们的rawRequest才能完成。如果不是(其他的),然后我们想要异步运行它。这意味着我们放入了两个请求,但是我们只等待另外一个请求。

记住保存新的条件语句,清空终端,然后让它工作。

优化速率限制:YouTube教程的GIF显示Zameer演示如何保存新的条件语句,清除终端并使其工作。

你可以看到API速率限制的增长非常缓慢,对吧?但随着时间的推移,如果你有一个无穷无尽的产品列表,并让它无限地运行,你会看到它开始消耗你的API速率限制。OB欧宝娱乐APP然而,我们仍然在500到568之间徘徊。这表明它并没有达到它所能达到的速度。

我们可以做得更好。我们可以提出更多的要求。

在此之前,我们将实现一些最佳实践,将条件语句关联到异步函数部分。我们要写const numberOfParallelRequests = 3,并将其粘贴到条件语句中。

当你再次运行它时,你的速率限制应该下降得更快。你应该能达到400甚至更低。这意味着我的应用程序运行得更快了,这很好。但在迭代这100个产品之前,它仍然没有达到其速率极限。

我们如何确保我们的运行速度尽可能接近限速?

尽可能接近你的利率限制:建立你的安全网

到目前为止,我们已经完成了一些主动优化,但我们绝对可以做得更好。我们的目标是使我们的numberOfParallelRequests越高越好,同时又不会超过速率极限也就是让极限为0。

我们要做的第一件事是建立一个安全网。这确保了即使您确实消耗了大量API速率限制并且它开始接近零,您也不会在接近速率限制时发出请求。

在下面的示例中,我将向您展示如何操作。

我们已经在日志中捕获并返回了可用速率限制console.log有${extensions.cost.throttleStatus。当前可用}速率限制点可用\n).

我们把它绑起来日志到一个变量,这样我们就可以随时使用。

为了做到这一点,你需要创建一个new变量在你的主函数中。在这个例子中,我们要把这个新变量设为0availableRateLimit = 0目前是这样。

然后你要设置你的availableRateLimit变量rawRequest的回调函数。它看起来像这样:

优化速率限制:YouTube教程的GIF显示Zameer将新的可变速率限制设置为零。然后他在条件下的两个原始请求回调函数中设置可用速率限制变量。

太棒了!这给了我们一种跟踪剩余量的方法。现在我们要设置阈值。

阈值阻止我们在低于设定的速率限制时发出请求。我们希望避免低于零,避免达到429个回复。

为了做到这一点,我们要定义另一个变量。我们叫它rateLimitThreshold,我们将把它设为50。50不是一个任意的数字。我们可以心算一下。我们知道每个突变需要10个查询点,我一次做了大约3个。也就是说,在完成一个请求所需的时间中使用了30个点。因此,30小于50。考虑到我们等待请求的时间大约是一秒钟,这个计算应该是正确的。

现在我预计有时我们会关闭,它会接近50,但那是我们的业务逻辑会保护我们。我们很快就会实现它。

使用阈值进行保护

那么业务逻辑是什么呢?

现在我们要看一下存储在my中的那个值是什么availableRateLimit变量。在我提出这些要求之后,我还剩下什么?如果它小于我的rateLimitThreshold,我们为自己定义的可接受阈值,然后我们想告诉我们的应用程序,“等一下。等一等。我们没有空间无限期地提出这些要求。”

“我们的目标是打造优秀的软件,这样我们就可以防止提出任何我们知道会达到我们的速率限制的请求。”

我们这样做是因为我们想避免点击一堆429,这可能会让Shopify认为我们是一个机器人。我们的目标是构建好的软件,这样我们就可以防止发出任何我们知道会命中429的请求。

为了做到这一点,我们将在下面的子句中编写:

优化速率限制:YouTube教程的截图显示,如果可用速率限制低于速率限制阈值,Zameer将编写日志等待。

这就是说如果availableRateLimit小于()<)rateLimitThreshold,我们在写a日志等。我们想让应用等待。要在Node.js中做到这一点,我们需要实现一个新的promise,等待新的承诺。在这个承诺中,我们将传递一个解决参数,我们将定义在承诺内发生的事情。

在本例中,它将是一个超时setTimeout。对于超时,我们将传入函数定义超时完成后发生的情况。在本例中,我们将用解析('速率限制等待')。然后再插入一个日志控制台。lot(“已完成等待-继续请求”)

你最不想提供的就是setTimeout(函数)超时长度的整数。数量是毫秒,所以我们要传入1000,这意味着我们总共要等待一秒钟。

你可能还喜欢:API速率限制和使用GraphQL

这是我们的故障保险,以确保我们永远不会达到我们的速率限制!这个条件现在是说,如果我们有少于可接受的50分可用,而不是通过整个循环同样,它会等待一秒钟,然后发出那些请求。

在运行该故障保护程序以查看其实际工作情况之前,我希望您更改您的查询去拿249产品S,因为250会让你每次查询的积分达到1000分。

好吧,继续运行吧!

当你低于48时,你应该看到a日志它看起来像这样:

优化速率限制:YouTube教程的截图显示,日志显示Zameer达到了速率限制阈值,必须等待一秒钟才能继续他的请求。

以上是日志说我们达到了阈值,必须等待一秒钟,现在我们完成了,继续我们的请求。

需要注意的一点是,当我们以这种方式运行这些promise时,会有一些非顺序输出日志这是由于我们的同步和异步rawRequests

每一个rawRequest执行它然后完成后立即回调。话虽如此,确保我们在低于阈值时不会发出更多请求的最终结果是正确的。如果您在终端中滚动,您将看到大量输出,但没有实际的错误,这很好。

运行最终查询

我想明确的一点是,在应用程序中实现逻辑只是确保优化速率限制而不超出限制的一个示例。这绝对不是唯一的解决方案。

在生产应用程序中,您可能有更多可用的选项。

  1. 您可以实现一个队列模型,将请求放入在多个线程之间共享资源的队列中。
  2. 你可以推迟一些执行,放弃一些idS存储到有cron作业或计划作业的数据库中。之后迭代每条记录并以有规律的节奏发出这些请求(例如:一天一次、一小时一次等)。

上面概述的方法应该让您了解我们如何理解我们的速率限制可用性是什么,以及您可以使用它做什么,例如在事情太接近时实现故障安全。

现在,如果我们再运行一次JS的执行,我们会看到我们有50个可用的速率限制点。当我们等待的时候,我们的数字又增加到几百,因为我们每等待一秒,就会多得到50个。

优化速率限制:来自YouTube教程的GIF展示了Zameer运行这个JavaScript的执行,以显示您等待的每一秒都可以获得50多个可用的速率限制点。

每一条线都是一个产品更新,但我从不担心它会达到我的速率限制,它总是被照顾,这就是目标。你要确保你正在优化和最大化你的api,而不是在构建一个快速的应用程序,为你正在开发的商家完成工作。

我希望你觉得这篇文章很有教育意义,它能帮助你更好地理解API速率限制是什么样子的,以及使用它的最佳实践。

借助Shopify合作伙伴计划发展您的业务

了解更多