首页 > 解决方案 > Appengine 运行的是旧版本的代码——堆栈跟踪与源代码不匹配

问题描述

我有一个 python27 appengine 应用程序。我的应用程序在代码初始化的早期生成了 500 错误,我可以在 GCP 控制台的 StackDriver 调试器中检查堆栈跟踪。

我已经修补了代码,并在相同的服务名称和版本名称(即gcloud app deploy --version=SAME)下重新部署。不幸的是,旧错误仍然出现,堆栈跟踪中的行号反映了错误部署中的文件。如果我使用代码查看器来调试错误,我会被带到在线查看器中更新的补丁代码——并且存在不匹配。它的行为就好像应用程序实例正在保留代码的先前快照。

我对 GAE 的新鲜度和最终一致性保证很模糊。我是否必须等待一切才能为最新部署的版本提供服务?我可以强制它立即使用更新的代码吗?

我尝试过的事情:

我最初认为这个问题与版本控制有关,即可能请求在具有相同版本的实例之间进行负载平衡,但每个实例的代码略有不同。我对管理为新请求选择哪个 GAE 实例的实际规则有点模糊(尤其是 GAE 是否尝试基于源 IP 重用以前的实例)。当以相同的版本名称重新部署不同的代码时,我也不清楚活动实例是否会立即被销毁。

为了排除这种可能性,我尝试推送到新版本名称,然后删除所有以前的版本(gcloud app versions list用于获取列表)。但这无济于事——尽管源代码在 GCP 控制台调试器中是最新的,但我仍然从旧代码中获得堆栈跟踪。等待几个小时也无济于事。

标签: google-app-engine

解决方案


我尝试了两件事:

  1. 在 GAE->Settings 中禁用和重新启用应用程序
  2. 我还注意到快照中上传了一些 .pyc 文件,因此我删除了这些文件并重新部署。

我发现 (1) 是停止所有正在运行的 appengine 实例的一种非常有效的方法。当您部署项目的新版本时,会创建流量拆分(即旧版本为 0%,新版本为 100%),但根据我的经验,如果最近使用过旧实例,它们可能仍在运行(尽管它们被配置为接收 0% 的流量)。切换立即将他们全部杀死。不幸的是,我发现我的旧代码在重新启用后仍在使用。

(2) 成功了。.pyc 被上传并不明显。我通过查看发现了它,GCP->StackDriver->Debug并在树快照中看到了 .pyc 文件。

我最近更新了我.gitignore以忽略项目的本地安装的 pip 运行时依赖项(的输出pip install -t lib requirements.txt)。我不想要 git 中的那些,但它们确实需要作为我的 appengine 项目的一部分发布。我已经#!.gitignore.gcloudignore. 但是,我忘记重新添加*.pyc到我的 .gcloudignore 中。

查看应用程序部署中包含的完整文件集的另一种方法是增加infogcloud app deploy 命令的详细程度——您会看到一个带有校验和的巨大 json 清单。我通常不会打开它,因为很难目视检查,但我会在那里发现 .pyc。


推荐阅读