背景/概述:
我们有一个 Python Web 应用程序,其中包含两个项目(staging/dev 和 production)中的三个环境。这些环境托管在 GCP 中,使用 Google App Engine Flexible Environment、Cloud SQL 和用于静态文件的 GCP bucket。这些环境运行良好,响应速度很快。我们决定将 staging/dev 环境拆分为两个独立的项目,以便我们可以调整 staging 环境,使其更接近生产环境。
问题:
我们以与暂存环境相同的方式设置开发项目。但是,在 Gunicorn 工作程序最终超时后,实例在几个请求之后变得无响应。在使用 Stack Driver 和 top 进一步调查后,我们注意到 App Engine 实例花费了大量时间等待 I/O。Top 不断报告 CPU 等待时间 (wa) 约为 90%。此外,当我们尝试通过 SSH 进入实例时,我们发现连接需要很长时间,有时需要 5 分钟或更长时间,有时根本无法连接。一旦我们进入,shell 中的体验就会非常滞后。使用 docker 命令,例如docker container ls
有时需要几分钟才能返回容器列表,有时没有返回结果并导致实例重新启动,另一方面,使用 top 效果很好。当我设法进入运行我们应用程序的 docker 容器时,体验大致相同,但很难追踪导致问题的 I/O,因为 shell 很快就会变得无响应。此外,如果我们让应用程序闲置大约半小时,我们可以一致地进入实例,但是在docker exec -it [id] /bin/bash
进入应用程序的docker容器时,事情很快就会变得没有响应。
观察到的情况
- 内存使用量约为 800Mb,剩余内存约为 200Mb。未使用虚拟内存。
- CPU 使用率通常只有个位数,大部分是系统(不计算等待 I/O)。
- 数据库 CPU 和 Ram 使用率极低。数据库还使用 SSD。
- 部署后,Google Cloud Bucket 配置正确并填充了静态文件。
- 尝试删除实例并重建它们并不能解决问题。
- 推送新版本并不能解决问题。
- 增加 Gunicorn 工作程序的超时时间有助于防止应用程序返回错误,但最终请求将开始超时或实例将重新启动。
- 我们已验证环境变量已正确更新,以反映新的 GCP 项目名称、存储桶和数据库。
- 运行相同代码的另外两个环境运行良好。
想法/TL;DR
我们的新开发环境/项目的配置有些问题,似乎导致 I/O 速度变慢。以前,此配置与我们在另一个项目中的暂存环境并行运行良好。从我们看到和想到的一切来看,我们的一切似乎都井然有序,但我们显然遗漏了一些东西。任何帮助和想法都将不胜感激。
答案1
解决方案是创建一个新项目。我们以相同的方式进行设置,只是使用 AppEngine Standard 而不是 Flex。然后,我们只需更新环境变量以使用新的 project-id、bucket-id 和服务帐户密钥,一切就都正常了。
要么是我们旧项目中某个配置选项有误,要么是 GCP 端出现了异常。我仍然觉得很奇怪,一个没有流量的新实例(因此我们的代码都没有执行)在apt-get
进入容器时会因为运行而死机。