由于 go 缓存层耗时过长,App Engine Golang 部署的云构建超时

由于 go 缓存层耗时过长,App Engine Golang 部署的云构建超时

我们正在 App Engine 标准环境上部署用 Golang 编写的服务。

多年来我们都没有遇到过这方面的问题,部署只需 2 到 5 分钟就能完成。

自一月份以来,我们发现其中一项服务的部署时间不断增加,直到上个月它开始有时超时,尽管这项服务并没有发生重大变化。

现在它几乎总是超时,而不是在 10 分钟超时之前部署。

我们的第一步是尝试增加这个超时限制。

我们查看了文档,发现gcloud config set app/cloud_build_timeout 900可以使用此方法将此超时时间增加到 15 分钟。所以我们尝试了这种方法,但 10 分钟后仍然超时。我们现在在文档中发现,这将改变 Flex 环境的超时时间,但不会改变标准环境的超时时间。

如上所述,我们并不真正理解为什么部署时间会增加,事实上,这项服务确实在不到 5 分钟的时间内就在生产中正确部署。

我们现在正在研究云构建摘要以了解有何不同,以下是我们的发现。

超时的构建使用了需要很长时间才能完成的 go 缓存层。

超时时,构建摘要将如下所示:

  • 第 0 步获取程序在 2 秒内完成
  • 第 1 步准备在 0 秒内完成
  • 第 2 步 预标记 7 秒内完成
  • 第 3 步探测器在 17 秒内完成
  • 第 4 步分析仪在 2 秒内完成
  • 第 5 步 修复器在 1 分 4 秒内完成
  • 第 6 步建造者在 34 秒内完成
  • 步骤 7 导出器在 7 分钟 54 分钟后超时

在正确部署的构建中(早在一月份,或者在仍然正确部署的生产中),我们看到步骤 5 需要几秒钟,步骤 7 需要约 2 分钟。

我们还发现,随着时间的推移,这一情况逐渐增加,耗费的时间越来越多,直到现在基本上超时。

以下是步骤 5 中有关此缓存层的构建摘要日志

2021-04-27 17:16:44.658 ICTStarting Step #5 - "restorer"
Info
2021-04-27 17:16:44.660 ICTStep #5 - "restorer": Already have image (with digest): eu.gcr.io/gae-runtimes/buildpacks/go113/builder:go113_20210406_1_13_15_RC00
Info
2021-04-27 17:16:46.238 ICTStep #5 - "restorer": Restoring data for "google.go.build:gocache" from cache
Info
2021-04-27 17:16:46.238 ICTStep #5 - "restorer": Retrieving data for "sha256:2b4be425fac1c997f7350663ff0406cc65bcff4acc894f8b07c0af09284a950e"
Info
2021-04-27 17:17:39.732 ICTFinished Step #5 - "restorer"

这里检索缓存层的数据花费了 53 秒,而以前只需几秒钟。

以下是第 7 步的日志

Info
2021-04-27 18:33:29.861 ICTStep #7 - "exporter": Adding cache layer 'google.go.build:gocache'
Info
2021-04-27 18:33:29.861 ICTStep #7 - "exporter": Layer 'google.go.build:gocache' SHA: sha256:6851017222d45b350217544670d113df46d630ffb51fc0c0a4bbb669c65d2178
Info
2021-04-27 18:39:57.199 ICTTIMEOUT
Info
2021-04-27 18:39:57.199 ICTERROR: context deadline exceeded

这里添加缓存层无法完成,因为整个构建现在需要超过 10 分钟,而以前完成第 7 步只需要大约 15 到 25 秒。

我们还注意到与该缓存层相关的​​一些错误有时会在成功构建时发生,但我们不确定这是否与时间增加有关。

Unable to delete previous cache image: DELETE https://eu.gcr.io/v2/xxxx/app-engine-tmp/build-cache/ttl-7d/xxxx/buildpack-cache/manifests/sha256:872c0a8965bc92689e2184fb277146bb05716e38352fb539115485c7d982dbcc: GOOGLE_MANIFEST_DANGLING_TAG: Manifest is still referenced by tag: dcd74554-d009-4147-8ddf-8fb36a67e92f

或者

Warning: Failed to export cache: committing cache: saving image 'eu.gcr.io/xxx/app-engine-tmp/build-cache/ttl-7d/xxx/buildpack-cache:latest': failed to write image to the following tags: [eu.gcr.io/xxx/app-engine-tmp/build-cache/ttl-7d/xxx/buildpack-cache:latest: PUT https://eu.gcr.io/v2/xxx/app-engine-tmp/build-cache/ttl-7d/xxx/buildpack-cache/manifests/latest: MANIFEST_INVALID: Failed to parse manifest for request "/v2/xxx/app-engine-tmp/build-cache/ttl-7d/xxx/buildpack-cache/manifests/latest": Manifest is missing required field "layers".]

我们正在尝试进一步调查此事,但目前尚无结果。

这可能是什么原因造成的?

热诚地。

答案1

我们通过一种变通方法解决了这个问题,即删除云存储 eu.artifacts.xxx/container 文件夹,因为它包含云构建恢复和导出的所有数据。

现在,构建再次可以在不到 2 分钟的时间内完成。

我们还添加了一个生命周期规则,以便在重新创建此文件夹一天后自动删除它。希望这可以防止构建时间再次增加。

请注意,这种解决方法对我们来说很好,因为我们不需要缓存层,我们所有的构建都在 2 分钟左右完成,并且不会因为缓存层而更快地完成,但您的构建可能并非如此。

还要注意,该文件夹可能以 us.container 开头,或者根据构建位置以其他前缀开头。

如果有人对这个问题有正确的答案,我们仍然很有兴趣听到。

相关内容