错误响应

标准错误响应

如果 Real Time Reporting API 请求成功,则 API 返回 200 状态代码。如果请求出现错误,该 API 会根据错误类型在响应中返回 HTTP 状态代码、状态和原因。此外,响应正文还将详细说明出错的原因。下面是一个错误响应示例:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "invalidParameter",
    "message": "Invalid value '-1' for max-results. Value must be within the range: [1, 1000]",
    "locationType": "parameter",
    "location": "max-results"
   }
  ],
  "code": 400,
  "message": "Invalid value '-1' for max-results. Value must be within the range: [1, 1000]"
 }
}

错误表

代码 原因 说明 建议采取的操作
400 invalidParameter 表示请求参数的值无效。错误响应中的 locationTypelocation 字段提供与无效值有关的信息。 在解决问题之前,请勿重试。您需要为错误响应中指定的参数提供有效值。
400 badRequest 表明查询无效。例如,父级 ID 缺失,或者所请求的维度或指标组合无效。 在解决问题之前,请勿重试。您需要更改 API 查询,才能使其有效。
401 invalidCredentials 表明授权令牌无效或已过期。 在解决问题之前,请勿重试。您需要获取新的身份验证令牌。
403 insufficientPermissions 表明对于查询中指定的实体,用户没有足够的权限。 在解决问题之前,请勿重试。您需要获取足够的权限,才能对指定实体执行相应操作。
403 dailyLimitExceeded 表明用户已超出每日配额(每个项目或每个数据视图(配置文件)的配额)。 在解决问题之前,请勿重试。您的每日配额已用尽。请参阅 API 限制和配额
403 userRateLimitExceeded 表明超出了每个用户每 100 秒的查询数限制。Google API 控制台中设置的默认值是每个用户每 100 秒 100 次查询。您可以在 Google API 控制台中将此限制提高到最多 1000。 使用指数退避算法重试。您需要降低发送请求的速率。
403 rateLimitExceeded 表明已超出项目每 100 秒查询次数的速率限制。 使用指数退避算法重试。您需要降低发送请求的速率。
403 quotaExceeded 表明已达到 Core Reporting API 中每个数据视图(配置文件)10 个并发请求的上限。 请使用指数退避算法重试。您需要等待至少一个正在处理的数据视图(配置文件)请求完成。
500 internalServerError 发生了内部服务器意外错误。 此查询的重试次数不得超过一次。
503 backendError 服务器返回了一个错误。 此查询的重试次数不得超过一次。

处理 500 或 503 响应

在负载过重或处理较大规模的更复杂请求时,可能会发生 500503 错误。对于较大规模的请求,请考虑缩短请求数据的时间段,此外,还应考虑实现指数退避。 发生这些错误的频率取决于数据视图(配置文件)以及与该数据视图关联的报告数据量;导致一个数据视图(配置文件)出现 500503 错误的查询,并不一定会导致该数据视图中的查询出错(配置文件不同)。

实现指数退避

指数退避是指客户端按照不断增加的时间间隔定期重试失败的请求的过程。这是网络应用的标准错误处理策略。Real Time Reporting API 在设计时就已考虑到了客户端可能会使用指数退避重试失败的请求。这除了是一项“要求”外,使用指数退避还能提高带宽使用效率、减少获得成功响应所需的请求数,并最大程度地提高并发环境中的请求吞吐量。

实现简单指数退避的流程如下。

  1. 向 API 发出请求
  2. 接收错误响应,其中包含一个可重试的错误代码
  3. 等待 1 秒 + random_number_milliseconds
  4. 重试请求
  5. 接收错误响应,其中包含一个可重试的错误代码
  6. 等待 2 秒 + random_number_milliseconds
  7. 重试请求
  8. 接收错误响应,其中包含一个可重试的错误代码
  9. 等待 4 秒 + random_number_milliseconds
  10. 重试请求
  11. 接收错误响应,其中包含一个可重试的错误代码
  12. 等待 8 秒 + random_number_milliseconds
  13. 重试请求
  14. 接收错误响应,其中包含一个可重试的错误代码
  15. 等待 16 秒 + random_number_milliseconds
  16. 重试请求
  17. 如果错误仍然出现,则停止重试并记录错误。

在上述流程中,random_number_milliseconds 是一个小于或等于 1000 的随机毫秒数。必须这样做才能在一些并行实现中避免某些锁定错误。random_number_milliseconds 必须在每次等待后重新定义。

注意:等待时间始终是 (2 ^ n) 秒 + random_number_milliseconds,其中 n 是单调递增的整数,初始值为 0。n 在每次迭代(每次请求)后递增 1。

该算法设置为 n 为 5 时终止。设置这个上限只是为了防止客户端无限重试,以便在大约总共 32 秒的延迟后,将请求认定为“不可恢复的错误”。

下面的 Python 代码就是上述流程的实现示例,旨在从名为 makeRequest 的方法出现的错误中恢复过来。

import random
import time
from apiclient.errors import HttpError

def makeRequestWithExponentialBackoff(analytics):
  """Wrapper to request Google Analytics data with exponential backoff.

  The makeRequest method accepts the analytics service object, makes API
  requests and returns the response. If any error occurs, the makeRequest
  method is retried using exponential backoff.

  Args:
    analytics: The analytics service object

  Returns:
    The API response from the makeRequest method.
  """
  for n in range(0, 5):
    try:
      return makeRequest(analytics)

    except HttpError, error:
      if error.resp.reason in ['userRateLimitExceeded', 'quotaExceeded',
                               'internalServerError', 'backendError']:
        time.sleep((2 ** n) + random.random())
      else:
        break

  print "There has been an error, the request never succeeded."