几次请求后超出用户速率限制

Posted

技术标签:

【中文标题】几次请求后超出用户速率限制【英文标题】:User rate limit exceeded after a few requests 【发布时间】:2017-07-22 07:01:58 【问题描述】:

我通过pydrive 使用 Google Drive API 在两个 Google Drive 帐户之间移动文件。我一直在测试一个包含 16 个文件的文件夹。我的代码总是在第六个文件中报错

"超出用户速率限制">

我知道请求数量有限制(10/s 或 1000/100s),但我已尝试使用 Google Drive API 建议的exponential backoff 来处理此错误。即使在 248 秒之后,它仍然会引发相同的错误。

这是我正在做的一个例子

def MoveToFolder(self,files,folder_id,drive):
    total_files = len(files)
    for cont in range(total_files):
        success = False
        n=0
        while not success:
            try:
                drive.auth.service.files().copy(fileId=files[cont]['id'],
                                                body="parents": ["kind": "drive#fileLink", "id": folder_id]).execute()
                time.sleep(random.randint(0,1000)/1000)
                success = True
            except:
                wait = (2**n) + (random.randint(0,1000)/1000)
                time.sleep(wait)
                success = False
                n += 1

我尝试使用“批处理请求”来复制文件,但它会为 10 个文件引发相同的错误。

def MoveToFolderBatch(self,files,folder_id,drive):
    cont=0
    batch = drive.auth.service.new_batch_http_request()
    for file in files:
        cont+=1
        batch.add(drive.auth.service.files().copy(fileId=file['id'],
                                                 body="parents": [
                                                     "kind": "drive#fileLink", "id": folder_id]))
    batch.execute()

有人有什么建议吗?

编辑: 根据谷歌支持:

关于您的用户速率限制超出错误,与控制台中设置的每用户速率限制完全无关。相反,它来自 Drive API 所依赖的内部 Google 系统,并且最有可能在单个帐户拥有域中的所有文件时发生。 我们不建议单个帐户拥有所有文件,而是让域中的个人用户拥有文件。对于传输文件,您可以查看此链接。另外,请检查此链接的建议以避免错误。

【问题讨论】:

【参考方案1】:

403: User Rate Limit Exceeded 基本上是防洪。


 "error": 
  "errors": [
   
    "domain": "usageLimits",
    "reason": "userRateLimitExceeded",
    "message": "User Rate Limit Exceeded"
   
  ],
  "code": 403,
  "message": "User Rate Limit Exceeded"
 

你需要放慢速度。像您所做的那样实施指数退避是正确的做法。

Google 在计算请求方面并不完美,因此您自己计算请求并没有真正的帮助。有时你可以一秒钟收到 15 个请求,而有时你只能得到 7 个。

您还应该记住,如果服务器上的负载很大,您正在与使用服务器的其他人一起完成您的请求,其中一个请求可能需要更长的时间,而另一个请求可能不会。不要在大多数人设置 cron 作业以进行提取的时间运行。

注意:如果您转到已启用驱动器 API 的谷歌开发者控制台,请点击

旁边的铅笔图标

每位用户每 100 秒的查询次数

每 100 秒的查询次数

你可以同时增加它们。一种是基于用户的,另一种是基于项目的。每个用户可以在 100 秒内发出 X 个请求,您的项目每 100 秒可以发出 Y 个请求。

注意:不知道你可以设置多高。这是我的开发帐户,所以它可能有一些我不记得的 beta 访问权限。

【讨论】:

谢谢,如果我有你的配额,我会做得更好!这是您的帐户类型吗? link 试试你的,看看会发生什么我不记得你可以设置的最大值是多少。 这是您的帐户link。这适用于 Web 应用程序吗? 您在哪里注册了您的应用程序console.developers.google.com 找到您的项目 转到库 找到您启用的驱动器 转到配额选项卡。 API就是API我不管是什么类型的项目 我正在使用最大免费账户。我可能会创建一个开发帐户。 Tks【参考方案2】:

见403 rate limit after only 1 insert per second和403 rate limit on insert sometimes succeeds

重点是:-

退避但不实施指数退避!。这只会扼杀您的应用程序吞吐量

相反,您需要主动限制您的请求以避免发生 304。在我的测试中,我发现最大可持续吞吐量约为每 1.5 秒 1 个事务。

批处理使问题变得更糟,因为在引发 304 之前对批处理进行了解包。 IE。一批10个被解释为10个快速交易,而不是1个。

试试这个算法

delay=0                              // start with no backoff
while (haveFilesInUploadQueue) 
   sleep(delay)                      // backoff 
   upload(file)                      // try the upload
   if (403 Rate Limit)              // if rejected with a rate limit
      delay += 2s                    // add 2s to delay to guarantee the next attempt will be OK
    else 
      removeFileFromQueue(file)      // if not rejected, mark file as done
      if (delay > 0)                // if we are currently backing off
         delay -= 0.2s               // reduce the backoff delay
      
   

// You can play with the 2s and 0.2s to optimise throughput. The key is to do all you can to avoid the 403's 

需要注意的一点是,云端硬盘存在(是?)一个错误,有时上传会因 403 被拒绝,但尽管发送了 403,云端硬盘仍会继续创建文件。症状将是重复的文件。因此,为了更加安全,在 403 之后,您应该以某种方式检查文件是否确实存在。最简单的方法是使用预先分配的 ID,或者将您自己的不透明 ID 添加到属性中。

【讨论】:

好吧,我尝试为每笔交易使用 1.5s 并且它有效,但现在它也可以使用 0.1s 的延迟。正如@DaImTo 所说,这可能取决于我使用 API 的时间。 酷。 1.5s 不是固定的,因此您可以随时尝试减少它,直到您开始看到 304,然后增加它直到它们停止。我有一个执行此操作的 javascript 库。在 Google 内部,使用存储桶/令牌机制限制速率。您从大约 25 个令牌开始,您可以随心所欲地使用它们。一旦您发送了 25 个请求,您的存储桶就为空,您在获得令牌之前无法再发送任何请求。令牌每 1.5 秒添加一次。注意。我提供的所有数据都是近似值,可能会发生变化,因此绝不能依赖。它们仅用于说明。 我无法理解这个系统。它一直工作到现在。之前,我复制了30个文件,没问题。然后,我再次尝试它开始再次引发错误。还有更多,我正在尝试复制一个包含 16 个文件的文件夹,问题始终在文件 7 中。它复制了前六个,但对于第七个它会引发错误。 这有点道理。您的前几个通常可以正常工作,因为您的存储桶有令牌。耗尽存储桶后,您将获得 304'd。您获得的 304 越多,您的应用程序就越被视为敌对。您只需要接受速率限制作为生活中的事实,并放慢速度以将其最小化(但不要指数退避)。正如我所说,我的库会自动调整延迟,根据我的经验(上传 100 个文件),它往往会稳定在每 1.5 秒左右一个。我会用我使用的算法更新我的答案。 不要做任何假设,但根据我的经验,它只写有速率限制的交易。如果您考虑 Drive 背后的大规模分布式文件系统,那么写入成本高昂且需要节流是有道理的。

以上是关于几次请求后超出用户速率限制的主要内容,如果未能解决你的问题,请参考以下文章

请求 gmail-api 时出现 HttpError 429:超出用户速率限制

使用 C# MVC 的 GMail API 超出用户速率限制

通过Node和Redis进行API速率限制

上传期间引发“超出速率限制”错误的速率限制是多少?

Tweepy 错误:请求超出帐户当前的包请求限制

批量查询超出速率限制