Cloud Scheduler 作业命中 HTTPS 端点并记录失败状态 502,但服务器返回成功响应状态 200

问题描述

我有一个云调度程序作业,它应该每小时访问我的 API 以更新一些价格。作业大约需要 80 秒才能运行。

这是它的作用:

POST https://www.example.com/api/jobs/update-prices

我的应用托管在 Firestore 上,/api/jobs/** 由名为 server-jobs 的云运行服务处理。

firebase.json

{
  "source": "/api/jobs/**","run": { "serviceId": "server-jobs","region": "europe-west1" }
},

几乎一切正常。查看来自我的 server-jobs 服务的日志:

enter image description here

您可以看到 Google-Cloud-Scheduler 用户代理。你可以看到所有的回复都是 200 OK。

但在 Cloud Scheduler 控制台上,作业似乎失败了:

enter image description here

查看云调度程序日志:

enter image description here

它记录了以下错误

状态 502“type.googleapis.com/google.cloud.scheduler.logging.AttemptFinished”

但是那个 502 根本不是来自我的服务器。

更多详情

我有 2 个不同的自定义域连接到该 Firebase 托管。并且该错误仅发生在其中一个域中。我有两个云调度程序作业(配置完全相同)到每个连接的域。

JOB 1 https://www.example1.com/api/jobs/update-prices SUCCEEDS (job takes ~35 seconds)
JOB 2 https://www.example2.com/api/jobs/update-prices FAILS (job takes ~80 seconds)

我认为工作持续时间与此无关。因为起初,我正在运行完全相同的工作,但直接点击 Cloud Run URL(不通过 Firebase 托管代理)并且它记录为成功。此错误仅在我开始访问连接的 Firebase 托管域而不是直接访问 Cloud URL 服务 URL 后才开始。

这些域名在不同的地方和不同的国家注册。但两者都已正确配置并且在生产中运行良好。

并且每次登录我的服务器都成功 200。

更新

我刚刚注意到一个模式:

enter image description here

似乎在作业启动后恰好 1 分钟(60 秒)触发了错误。所以工作的持续时间可能与它有关。因为需要 80 秒的作业“失败”,而另一个需要 35 秒的作业成功。这是超时问题吗?什么是返回 502?因为我的服务器按预期工作,正如您从日志中看到的那样。

更新 2

我刚刚用 gcloud scheduler jobs descript JOB_NAME 检查了作业,它们都配置了 attemptDeadline: 180s。所以我的工作时长应该没有问题,因为它们都在 180 秒以下。

更新 3

正如我所怀疑的,工作持续时间似乎是这里的问题。

我已经对我的 API 处理程序函数进行了以下测试:

  • 等待 59 秒,然后 res.sendStatus(200)
  • 结果:Cloud Scheduler 将两个作业都显示为成功

还有:

  • 等待 65 秒,然后 res.sendStatus(200)
  • 结果:Cloud Scheduler 将两个作业都显示为失败

似乎沿着这条链有一个 60 秒的门槛:

  • 云调度程序
  • Firebase 托管
  • 云运行

解决方法

我猜 Firebase 托管是罪魁祸首。

Firebase 托管有一个默认的 60 秒请求超时。这就是为什么即使在服务器上成功,作业也会看到错误的原因。

来自:https://firebase.google.com/docs/hosting/functions

注意:Firebase 托管受 60 秒请求超时的影响。即使您将 HTTPS 函数配置为更长的请求超时,如果您的函数需要超过 60 秒的运行时间,您仍会收到 HTTPS 状态代码 504(请求超时)。要支持需要较长计算时间的动态内容,请考虑使用 App Engine 柔性环境。