首页 > 解决方案 > 部署到 AWS 时,gunicorn 上的 CRITICAL Worker TIMEOUT

问题描述

我有一个使用 gunicorn 服务器的烧瓶网络应用程序,并且我使用了 gevent 工人类,因为它以前帮助我以前没有遇到[CRITICAL] WORKER TIMEOUT问题,但是由于我已经将它部署到 ELB 后面的 AWS 上,我似乎又遇到了这个问题.

我之前尝试过eventlet工人阶级,但没有奏效,但gevent在当地做了

这是我用作 Dockerfile 入口点的 shell 脚本:

gunicorn -b 0.0.0.0:5000 --worker-class=gevent --worker-connections 1000 --timeout 60 --keep-alive 20 dataclone_controller:app

当我检查 pod 上的日志时,这是唯一打印出来的信息:

[2019-09-04 11:36:12 +0000] [8] [INFO] Starting gunicorn 19.9.0
   [2019-09-04 11:36:12 +0000] [8] [INFO] Listening at: 
   http://0.0.0.0:5000 (8)
   [2019-09-04 11:36:12 +0000] [8] [INFO] Using worker: gevent
   [2019-09-04 11:36:12 +0000] [11] [INFO] Booting worker with pid: 11
   [2019-09-04 11:38:15 +0000] [8] [CRITICAL] WORKER TIMEOUT (pid:11)

标签: pythonamazon-web-servicesflaskdockerfilegunicorn

解决方案


对于我们的 Django 应用程序,我们最终将其归结为内存耗尽。这很难追踪,因为 AWS 监控不提供内存统计信息(至少在默认情况下),即使提供了,也不清楚瞬态峰值有多容易看到。

其他症状包括:

  • 在这一点上,我们经常会失去与 VM 的网络连接。
  • /var/log/syslog 包含一些进程重新启动的证据(在我们的例子中,这主要是 Hashicorp 的 Consul)。
  • 没有证据表明 Linux OOM 检测起作用。
  • 我们知道系统很忙,因为 AWS CPU 统计数据经常会显示峰值(比如 60%)。

对我们来说,解决方法在于明智地转换 Django 查询,如下所示:

   for item in qs:
       do_something()

像这样使用.iterator()

CHUNK_SIZE = 5
...
   for item in qs.iterator(CHUNK_SIZE):
       do_something()

这有效地交换了数据库往返以降低内存使用量。请注意,CHUNK_SIZE = 5 是有意义的,因为我们正在获取一些带有列 JSONB 的数据库对象。我希望更典型的用法可能会使用大几个数量级的数字。


推荐阅读