9

作为 API 调用的一部分,我在 Google App Engine Flexible 上运行了一个函数。结构是这样的

import externalmod
...
...

@app.route('/calc_here')
def calc:
answer = externalmod.Method()

return answer

函数 externalmod 是一个复杂的算法(不是数据存储,不是 urlfetch,只是纯 python),它适用于桌面上的所有可能情况,但对于应用程序引擎上的某些输入情况,当调用端点时,它会给出以下错误

{
 "code": 13,
 "message": "BAD_GATEWAY",
 "details": [
  {
   "@type": "type.googleapis.com/google.rpc.DebugInfo",
   "stackEntries": [],
   "detail": "application"
  }
 ]
}

在查看https://cloud.google.com/appengine/articles/deadlineexceedederrors和以下讨论后: 如何增加 Google App Engine 请求计时器。默认为 60 秒

https://groups.google.com/forum/#!topic/google-appengine/3TtfJG0I9nA

我意识到这是因为如果任何代码运行超过 60 秒,App 引擎就会停止。我首先尝试根据Should Exception catch DeadlineExceededError 异常进行以下操作?

from google.appengine.runtime import DeadlineExceededError
try:
   answer = externalmod.Method()
except DeadlineExceededError:
   answer = some_default

但我得到了没有模块 google.appengine 的错误

然后意识到所有文档都是针对标准环境的,但是我使用的是灵活的环境,我认为这个 appengine.runtime 可能甚至不再存在当我这样做时:

 try:
   answer = externalmod.Method()
 except :
   answer = some_default

它奏效了,我开始发现一些 DeadlineExceededErrors。但显然,我不能总是像这样捕获 DeadlineExceededErrors。有时我会发现错误,有时不会。我认为最好的方法是增加允许代码运行的时间,而不是仅仅捕获异常。

我尝试通过添加 CPU:2 来更改 app.yaml 文件,但没有任何区别。

runtime_config:
python_version: 3
resources:
  cpu: 2
  memory_gb: 4
manual_scaling:
  instances: 1

也许这个问题Taskqueue for long running tasks in FLEXIBLE app engine

也可能有类似的答案,但我不知道任务队列是什么,而且我不能排队任何东西,因为我正在运行的关键功能是独立的,我不想只在某些情况下分解它。对我来说,增加 60 秒的限制会更容易。我怎样才能做到这一点?

4

1 回答 1

17

由于我没有得到任何答案,我继续搜索。我意识到许多其他人也有类似的问题。

首先要注意的是,GAE 柔性环境不像标准环境那样具有大多数标准约束。这意味着DeadlineExceededError不存在,因为没有 60 秒的最后期限。所有模块和代码都像在任何计算机上一样运行,因为它们都包含在 Docker 容器中。

https://cloud.google.com/appengine/docs/flexible/python/migrating

此外,没有 google.appengine 模块。根据所使用的语言,所有云交互都应通过 google.cloud API https://cloud.google.com/apis/docs/overview进行

那么什么可以解释这个超时呢?我检查了谷歌云项目控制台中的日志记录-logs。我看到相关错误实际上是[CRITICAL] WORKER TIMEOUT在调用函数后 30 秒发生的。这与 GAE flex 无关,而是与服务器框架有关。在我的情况下,'gunicorn'。

实际上在这里提供了答案https://serverfault.com/questions/490101/how-to-resolve-the-gunicorn-critical-worker-timeout-error/627746

基本上,使用文档http://docs.gunicorn.org/en/latest/settings.html#config-file

唯一需要的更改是在 app.yaml 文件中

早在哪里

runtime: python
env: flex
entrypoint: gunicorn -b :$PORT main:app

gunicorn 工人有一个默认的 30 秒超时

将其更改为

entrypoint: gunicorn -t 120 -b :$PORT main:app

这里的超时时间是 120 秒,但是根据一些试验和错误,它可以被优化。然而,这解决了我运行比平时更长的代码的特殊问题

于 2018-06-04T17:39:13.563 回答