问题描述
我有一个云调度程序作业,它应该每小时访问我的 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
服务的日志:
您可以看到 Google-Cloud-Scheduler
用户代理。你可以看到所有的回复都是 200 OK。
但在 Cloud Scheduler 控制台上,作业似乎失败了:
查看云调度程序日志:
它记录了以下错误:
状态 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。
更新
我刚刚注意到一个模式:
似乎在作业启动后恰好 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 柔性环境。