问题排查概览

本页面提供 API Gateway 的一般问题排查信息。

无法运行“gcloud api-gateway”命令

如需运行 gcloud api-gateway ... 命令,您必须已更新 Google Cloud CLI 并启用必要的 Google 服务。如需了解详情,请参阅配置开发环境。

命令“gcloud api-gateway api-configs create”表示服务账号不存在

如果您运行 gcloud api-gateway api-configs create ... 命令并收到以下形式的错误:

ERROR: (gcloud.api-gateway.api-configs.create) FAILED_PRECONDITION:
Service Account "projects/-/serviceAccounts/service_account_email" does not exist

重新运行该命令,但这次包含 --backend-auth-service-account 选项,以明确指定要使用的服务账号的电子邮件地址:

gcloud api-gateway api-configs create CONFIG_ID \
  --api=API_ID --openapi-spec=API_DEFINITION \
  --backend-auth-service-account=SERVICE_ACCOUNT_EMAIL

确保您已按照配置开发环境中的说明为服务账号分配了必要的权限。

确定 API 错误响应的来源

如果对已部署 API 的请求导致错误(HTTP 状态代码 400 到 599),则可能无法从响应本身清楚地了解错误是源自网关还是源自后端。如需确定这一点,请执行以下操作:

  1. 前往“Logs Explorer”页面,然后选择您的项目。

    转到日志浏览器

  2. 使用以下日志查询过滤到相关网关资源:

    resource.type="apigateway.googleapis.com/Gateway"
    resource.labels.gateway_id="GATEWAY_ID"
    resource.labels.location="GCP_REGION"

    其中:

    • GATEWAY_ID 指定网关的名称。
    • GCP_REGION 是所部署网关的 Google Cloud 区域。
  3. 找到与您要调查的 HTTP 错误响应匹配的日志条目。例如,按 httpRequest.status 过滤。

  4. 检查 jsonPayload.responseDetails 字段的内容。

如果 jsonPayload.responseDetails 字段的值为 "via_upstream",则错误响应源自您的后端,您需要直接排查后端问题。如果是任何其他值,则错误响应来自网关;请参阅本文档的以下部分,了解更多问题排查提示。

API 请求返回 HTTP 403 错误

如果对已部署 API 的请求向 API 客户端返回 HTTP 403 错误,则表示请求的网址有效,但由于某种原因禁止访问。

部署的 API 具有与授予您在创建 API 配置时使用的服务账号的角色相关联的权限。通常,出现 HTTP 403 错误的原因是服务账号没有访问后端服务所需的权限。

如果您在同一 Google Cloud 项目中定义了 API 和后端服务,请确保为服务账号分配了 Editor 角色或访问后端服务所需的角色。例如,如果后端服务是使用 Cloud Run functions 实现的,请确保为服务账号分配了 Cloud Function Invoker 角色。

API 请求返回 HTTP 401 或 500 错误

如果对已部署 API 的请求向 API 客户端返回 HTTP 401 或 500 错误,则可能是使用创建 API 配置时所用的服务账号调用后端服务时出现问题。

已部署的 API 具有与您在创建 API 配置时使用的服务账号所授予的角色关联的权限。系统会检查服务账号,以确保它都存在,并且可在部署 API 时由 API 网关使用。

如果在部署网关后删除或停用服务账号,则可能会发生以下事件序列:

  1. 删除或停用服务账号后,您可能会在网关日志中看到 401 HTTP 响应。如果日志条目的 jsonPayload 中的 jsonPayload.responseDetails 字段设置为 "via_upstream",则表示删除或停用服务账号是导致错误的原因。

  2. 您可能还会看到 HTTP 500 错误,但 API Gateway 的日志中没有任何相应的日志条目。如果服务账号被删除或停用后,您的网关没有立即收到请求,您可能不会看到 HTTP 401 响应,但没有相应 API 网关日志的 HTTP 500 错误表明网关的服务账号可能不再有效。

如果失败请求的后端是另一个 Google Cloud API(例如 bigquery.googleapis.com),您会在网关日志中看到 401 HTTP 响应,其中 jsonPayload.responseDetails 字段设置为 "via_upstream"。这是因为 API Gateway 使用 Google Cloud ID 令牌向后端进行身份验证,而其他 API 需要访问令牌。

API 请求针对强制执行配额的方法返回 HTTP 500 错误

如果您收到以下错误,则表示网关无法为您的请求分配配额:

HTTP/2 500
{"code":500,"message":"Failed to call Service Control Quota."}

当您调用配置了配额的方法,但该 API 的配额指标不再存在时,通常会发生此错误。在 gRPC 网关上,同一故障会作为 gRPC 状态代码 Internal 返回。

在网关日志中确认原因

  1. 前往“Logs Explorer”页面,然后选择您的项目。

    转到日志浏览器

  2. 运行以下日志查询:

    resource.type="apigateway.googleapis.com/Gateway"
    resource.labels.gateway_id="GATEWAY_ID"
    jsonPayload.responseDetails="service_control_quota_error"
    httpRequest.status=500

    其中,GATEWAY_ID 指定网关的名称。

    该查询会过滤状态代码以及 jsonPayload.responseDetails,因为 API Gateway 会对每个配额拒绝使用相同的 responseDetails 值。合法超出其配额的请求会生成相同的值,httpRequest.status 为 429。

  3. 检查所有匹配条目的 jsonPayload.apiConfig 和 jsonPayload.apiMethod 字段。它们会标识 API 配置和配额配置无效的方法。

为什么 API 配置可能具有无效的配额配置

您可以在 API 配置中定义配额指标和限制,但 API Gateway 会将其应用于整个 API。每次创建 API 配置时,它声明的指标和限制都会替换 API 的先前 API 配置声明的指标和限制。系统只会强制执行最近创建的 API 配置中的值。

相比之下,每个方法使用的指标是在网关提供的 API 配置中定义的。如果网关运行的是旧版 API 配置,则会要求 Service Control 针对其自身配置中存在但 API 中可能不存在的指标分配配额。如果该指标不存在,则分配调用会失败,并且网关会拒绝该请求。

例如,以下序列会导致第一个网关损坏:

  1. 您创建 API 配置 config-v1(用于声明指标 quota-metric-v1),并将其部署到 gateway-1。
  2. 您为同一 API 创建 API 配置 config-v2,该配置声明了指标 quota-metric-v2,并将其部署到 gateway-2。

gateway-2 有效,但对 gateway-1 的强制配额方法的请求开始失败,因为不再为 API 定义 quota-metric-v1。

以下更改可能会导致仍使用早期 API 配置部署的任何网关出现错误:

  • 重命名或移除指标。
  • 更改配额上限适用的指标。
  • 更改每个方法的配额费用中指定的指标(对于 OpenAPI 文档,为 x-google-quota;对于 gRPC 服务配置,为 quota.metric_rules)。

仅更改限制的值不会导致错误。不过,由于限制也会在 API 级别应用,因此新值会在该 API 的每个网关上强制执行,包括使用早期 API 配置部署的网关。

比较已部署的配额配置

  1. 列出您的网关以及每个网关提供的 API 配置:

    gcloud api-gateway gateways list \
     --format="table(name.basename(),apiConfig)"
  2. 列出受影响 API 的 API 配置,最近创建的配置排在最前面:

    gcloud api-gateway api-configs list --api=API_ID \
     --format="table(name.basename(),createTime:sort=1:reverse)"

    第一个条目是 API 配置,其配额指标和限制会针对整个 API 强制执行。使用 --format 标志进行排序,如下所示:此命令不支持 --sort-by 标志,并且不会以可预测的顺序返回 API 配置。

  3. 显示创建 API 配置所依据的 API 定义:

    gcloud api-gateway api-configs describe CONFIG_ID --api=API_ID \
     --view=FULL --format="value(openapiDocuments[0].document.contents)" \
     | tr '_-' '/+' | base64 --decode

    tr 命令是必需的,因为 contents 字段采用 base64url 编码,base64 --decode 无法直接读取。

    对于 gRPC API,配额配置位于服务配置中,而不是 OpenAPI 文档中,因此请将 openapiDocuments[0].document.contents 替换为 managedServiceConfigs[0].contents。

  4. 针对第 2 步中列表顶部的 API 配置运行第 3 步中的命令,然后针对第 1 步中显示为仍部署到网关的其他每个 API 配置运行该命令。

  5. 比较结果。旧版 API 配置中针对其方法收费的每个指标也必须在最近创建的 API 配置中定义。如果该配置中缺少某个指标,则提供旧 API 配置的网关会失败。

恢复有效的配额配置

审核您的配额指标和限制,确保它们在所有有效配置中保持一致。为此,请执行以下操作之一:

  • 如更新网关中所述,更新 API 的每个网关以使用最近创建的 API 配置。
  • 创建一个新的 API 配置,用于声明仍部署的 API 配置所使用的每个指标,并将现有网关保留在其当前 API 配置中。

为避免分配错误,请在 API 的 API 配置中保持指标名称一致。更改配额时,请更改限制的值,而不是指标的名称。

高延迟 API 请求

与 Cloud Run 和 Cloud Run functions 一样,API Gateway 也会受到“冷启动”延迟时间的影响。如果您的网关在 15 到 20 分钟内未收到流量,则在冷启动的前 10 到 15 秒内向网关发出的请求将出现 3 到 5 秒的延迟。

如果问题在初始“预热”期后仍然存在,请检查您在 API 配置中配置的后端服务的请求日志。例如,如果后端服务是使用 Cloud Run functions 实现的,请检查关联的 Cloud Function 请求日志的 Cloud Logging 日志条目。

无法查看日志信息

如果您的 API 响应正确,但日志不包含数据,这通常表示您尚未启用 API Gateway 所需的所有 Google 服务。

API Gateway 要求您启用以下 Google Cloud 服务:

名称 服务名称
API Gateway API apigateway.googleapis.com
Service Management API servicemanagement.googleapis.com
Service Control API servicecontrol.googleapis.com

如需启用所需的服务,请执行以下操作:

Google Cloud 控制台

  1. 在 Google Cloud 控制台中,前往 API 和服务 > API 库页面。

    转到 API 库

  2. 在 API 库页面上,在搜索栏中输入所需的 API 名称。
  3. 在搜索结果中,选择 API 页面。
  4. 在 API 页面上,点击启用。
  5. 对上表中列出的每项服务重复上述步骤。

Google Cloud CLI

使用以下命令启用这些服务:

gcloud services enable apigateway.googleapis.com
gcloud services enable servicemanagement.googleapis.com
gcloud services enable servicecontrol.googleapis.com

如需详细了解 gcloud 服务,请参阅 gcloud 服务。