【问题标题】:Google App Engine application deployment fails despite readiness_check returning an 200 status response尽管 readiness_check 返回 200 状态响应,但 Google App Engine 应用程序部署失败
【发布时间】:2020-01-03 15:04:47
【问题描述】:

我正在尝试为我的应用程序设置一个readiness_check。这是我app.yaml的相关部分:

readiness_check:
  path: '/readiness_check'
  check_interval_sec: 30
  timeout_sec: 4
  failure_threshold: 10
  success_threshold: 1
  app_start_timeout_sec: 300

(Full config)

我正在开发的项目是一个在 Express 上运行的 Node.js 应用程序。以下是我处理/readiness_check 端点的方式:

app
  .get(['/readiness_check'], (req, res) => res.sendStatus(200))

如果没有配置readiness_check,我的部署过程会成功,我可以毫无问题地访问我的应用程序。但是,当我包含 readiness_check 时,该过程将失败并出现以下错误:

OperationError:错误响应:[4] 您的部署未能在分配的时间内变得健康,因此被回滚。如果您认为这是一个错误,请尝试调整“readiness_check”部分中的“app_start_timeout_sec”设置。

我检查了日志,我可以看到/readiness_check 最初返回了502(当应用程序仍在启动时),然后开始返回200 状态代码。手动使用curl 访问端点显示了相同的结果。但由于某种原因,GCP 仍然认为我的部署并不健康。

运行gcloud app describe 确认我已启用splitHealthChecks 功能。

我浏览了troubleshooting sections in the documentation,发现我没有启用servicecontrol.googleapis.com 和endpoints.googleapis.com 服务,所以我启用了它们,但这也无济于事。

我还在文档中看到了以下注释:

如果您检查应用程序的 nginx.health_check 日志,您可能会发现运行状况检查轮询发生的频率比您配置的要高,这是因为冗余的运行状况检查器也遵循您的设置。这些冗余的运行状况检查器是自动创建的,您无法对其进行配置。

这可能是一个不相关的问题,但我在我的应用程序日志中找不到nginx.health_check。我尝试搜索“nginx”文本,但没有看到任何与健康检查相关的内容。虽然在寻找“readiness_check”,但它确实向我展示了我上面提到的回复。

【问题讨论】:

标签: google-app-engine google-cloud-platform


【解决方案1】:

可能有更多可能的方法来解决这个问题:

1) 您可以在您的app.yaml 文件中增加resources 量规中的值。你可以查看更多关于这个here的信息。

2) 您可以将app_start_timeout_sec 的值增加到the maximum value,即1800。这样您就可以给您的应用更多的时间来恢复健康。

3) 即使运行 gcloud app describe 确认您已启用 splitHealthChecks 功能,您是否执行了从旧版本迁移运行状况检查的所有正确步骤?它是否适用于您应用的所有版本,甚至是旧版本? 您可以仔细检查转换运行状况检查here 所需的所有步骤。应用命令gcloud app update --split-health-checks --project [YOUR_PROJECT_ID] 可能还不够。

编辑: 即使从理论上讲,如果您没有split your traffic across different versions,这应该不是问题(我想不出为什么会这样)。在有关迁移的文档中,在第 2 步中,它说:

为您的应用程序中的每个版本转换旧版运行状况检查选项。

为此,您应该为每个版本相应地编写和更新app.yaml,然后将服务部署为assigned to a certain version ID。例如:gcloud app deploy --project PROJECT_ID --version VERSION_ID --no-promote

4) 作为一种解决方法,您可以“伪造”readiness_check 响应,在一定时间后给出 200 状态响应。您必须在 this section 中添加自定义处理程序。这样部署就不会超时,并且会继续在后台工作。但是,这错过了准备情况检查的目的,因为您的实例可能会在尚未准备好时收到流量。如果您考虑到这一点,并且可以在您的应用程序中处理此问题,那么这将是一个可以考虑的选项。

最后,我假设您使用的是 App Engine Flex,至于标准版本,健康检查不可用,并且会出现错误。您可以查看this discussion here。

【讨论】:

  • 感谢您的回答!在我看来,1 和 2 在我的情况下不是问题,因为该应用程序之前确实使用过这么多的资源,并且我能够在检查超时之前访问我的应用程序并手动确认工作端点。但我不能对第三点说同样的话。我如何确保该功能也适用于我的应用程序的旧版本?很明显,我只在我尝试部署的最新版本中引入了新的健康检查配置。这是否意味着旧版本仍然使用旧的健康检查?
  • 我已经编辑了我的答案,详细说明了我为什么这么认为以及如何做到这一点。我仍然认为增加 app_start_timeout_sec: 1800 值得尝试。如果您说您的应用最初失败,然后一切正常,您只需给运行状况检查“更多时间思考”。
  • 你是对的,增加 app_start_timeout_sec 确实有帮助。我害怕增加超时时间,认为 gcloud 在指定时间过去之前不会执行任何检查,但似乎我误解了这一点。奇怪的是 gcould 无法访问我的应用程序的 readiness_check 端点,但我可以(而且我敢肯定在它决定中止部署过程之前至少有一分钟)。也许我只能访问其中一个实例,但并非所有实例都准备好了。再次感谢您!
  • 是的...调试模式告诉我启动我的应用程序的所有实例大约需要 14 分钟,所以我认为 5 分钟就足够的假设是完全错误的:D
猜你喜欢
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
  • 2020-02-17
  • 1970-01-01
  • 2019-03-16
  • 2015-11-13
  • 2019-04-22
  • 2016-09-15
相关资源
最近更新 更多