【问题标题】:Gunicorn sync workers spawning processesGunicorn 同步工作者生成进程
【发布时间】:2015-11-25 01:53:34
【问题描述】:

我们在我们的服务器中使用 Django + Gunicorn + Nginx。问题是,过了一段时间,我们看到很多 Gunicorn 工作进程变成了孤儿,还有很多其他的变成了僵尸。我们还可以看到一些 Gunicorn 工作进程产生了一些其他 Gunicorn 工作人员。我们最好的猜测是,这些工人在其父母工人去世后成为孤儿。
为什么 Gunicorn 工人会产生童工?他们为什么会死?!我们如何防止这种情况发生?
我还应该提到,我们已将 Gunicorn 日志级别设置为 debug,但我们仍然没有看到任何重要的东西,除了工人数量的定期日志,它报告了我们想要从中获得的工人数量。

更新 这是我们用来运行 gunicorn 的行:

gunicorn --env DJANGO_SETTINGS_MODULE=proj.settings proj.wsgi --name proj --workers 10 --user proj --group proj --bind 127.0.0.1:7003 --log-level=debug --pid gunicorn.pid --timeout 600 --access-logfile /home/proj/access.log --error-logfile /home/proj/error.log

【问题讨论】:

  • 你能发布你的 Gunicorn 配置吗?如果不知道它是如何设置的,就很难理解会发生什么。
  • 您的问题有什么更新吗?您是否想出了解决方案或找出问题所在?
  • 这是很久以前的事了,我问了这个问题一两天后,我们从gunicorn改为uWSGI,但没有找到解决方案。
  • 您需要一个监视器,因为您可能需要集成 supervisord 以在它失败时重新启动。并将所有这些 gunicorn 行传递给 .sh 文件。

标签: django fork gunicorn


【解决方案1】:

在我的例子中,我部署在 Ubuntu 服务器(LTS 版本,现在几乎是 14.04 LTS 服务器)并且我从来没有遇到过 gunicorn 守护进程的问题,我创建了一个 gunicorn.conf.py 并使用这个配置从新贵启动 gunicorn /etc/init/djangoapp.conf中这样的脚本

description "djangoapp website"
start on startup
stop on shutdown
respawn
respawn limit 10 5

script
  cd /home/web/djangoapp
  exec /home/web/djangoapp/bin/gunicorn -c gunicorn.conf.py -u web -g web djangoapp.wsgi
end script

我使用 .py 文件配置来配置 gunicorn,并设置了一些选项(详情如下)并在 /home/web/djangoapp 中部署我的应用程序(使用 virtualenv),并且僵尸和孤儿 gunicorn 进程没有问题。

我验证了您的选项,超时可能是一个问题,但另一个问题是您没有在配置中设置 max-requests,默认情况下为 0,因此,您的守护进程中不会自动重新启动工作程序,并且可能会产生内存泄漏( http://gunicorn-docs.readthedocs.org/en/latest/settings.html#max-requests)

【讨论】:

  • 我们正在使用主管,然后当我们看到问题时,我们认为这是由于主管而发生的。我们删除了它,问题仍然存在。
  • 好的,现在我的答案是,您是否在使用 uwsgi 并且问题仍然存在?你现在用哪一个代替主管?
  • 我们正在使用 uwsgi 自己的守护进程机制(没有主管),不,问题不存在。
  • 好吧,uwsgi 是基于 C 的,gunicorn 是基于 Python 的,我看到的唯一区别是超时,我使用 gunicorn 默认超时(30 秒),我看到你的情况是 10 分钟(600 秒)可能对您的应用程序来说太多时间(如果您需要更多时间,可能是 60/120 秒)。 uwsgi 更具侵略性,--harakiri 用于强制杀死 python 进程的超时。
  • 这是一个我们内部使用的应用程序,它占用大量 CPU。所以我们需要 10 分钟(在某些情况下)。我们在这两种情况下都将超时设置为 10 分钟。如果在我们将超时时间设置为 10 分钟时 gunicorn 中断,我称之为错误。
【解决方案2】:

我们将使用 .sh 文件来启动 gunicorn 进程。稍后您将使用 supervisord 配置文件。 what is supervisord?一些外部知道如何使用Django,Nginx,Gunicorn安装supervisord的信息链接Here

gunicorn_start.sh 记得给文件加上 chmod +x。

#!/bin/sh
NAME="myDjango"
DJANGODIR="/var/www/html/myDjango"
NUM_WORKERS=3
echo "Starting myDjango -- Django Application"
cd $DJANGODIR
exec gunicorn -w $NUM_WORKERS $NAME.wsgi:application --bind 127.0.0.1:8001

mydjango_django.conf :记得在你的操作系统上安装 supervisord。和 将其复制到配置文件夹中。

[program:myDjango]
command=/var/www/html/myDjango/gunicorn_start.sh
user=root
autorestart=true
redirect_sderr=true

稍后使用命令:

重新加载守护程序的配置文件,无需添加/删除(无需重新启动)

supervisordctl reread

重启所有进程 注意:restart 不会重新读取配置文件。为此,请参阅重读和更新。

supervisordctl start all

获取所有进程状态信息。

supervisordctl status 

【讨论】:

  • 这没有帮助。仍然可以看到那些孤儿进程。
【解决方案3】:

这听起来像是超时问题。

您有多个超时,它们都需要按降序排列。看来他们可能不是。

例如:

  • Nginx 的默认超时时间为 60 秒
  • Gunicorn 的默认超时时间为 30 秒
  • Django 的默认超时时间为 300 秒
  • Postgres 默认超时很复杂,但让我们为这个示例设置 60 秒。

在这个例子中,当 30 秒过去了,Django 仍在等待 Postgres 响应。 Gunicorn 告诉 Django 停止,而后者又应该告诉 Postgres 停止。 Gunicorn 在杀死 django 之前会等待一定的时间,让 postgres 进程成为孤立查询。用户将重新启动他们的查询,这次查询将花费更长的时间,因为旧查询仍在运行。

我看到您已将 Gunicorn tiemeout 设置为 300 秒。

这可能意味着 Nginx 告诉 Gunicorn 在 60 秒后停止,Gunicorn 可能会等待等待 Postgres 或任何其他底层进程的 Django,当 Nginx 厌倦了等待时,它会杀死 Gunicorn,让 Django 挂起。

这仍然只是一个理论,但它是一个非常常见的问题,希望能将您和遇到类似问题的任何其他人带到正确的地方。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-20
    • 1970-01-01
    • 2015-06-14
    • 2020-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多