Python中使用supervisor管理gunicorn进程的问题

当使用 supervisor 来管理 gunicorn 的时候,supervisor 配置文件 myapp.conf 中的 command 为:

gunicorn -w4 -b0.0.0.0:8000 run:app 注:这是一个 flask 项目

然后用命令 sudo supervisord -c myapp.conf 启动项目

此时可以查找多条 gunicorn 进程,同时测试接口可用

那么如何关闭这些 gunicorn 进程呢?

实测用 sudo supervisorctl -c myapp.conf stop myapp 命令可以使接口不可访问,但是那些 gunicorn 进程还是存在,当我再次重启 sudo supervisorctl -c myapp.conf start myapp 的时候,进程又多了四个。

我应该如何利用 supervisor 来关闭这些 gunicorn 进程呢?


Python中使用supervisor管理gunicorn进程的问题

15 回复

supervisor 配置加个 killasgroup=true 试试


这个问题我遇到过。用supervisor管理gunicorn确实比直接跑更稳定,但配置上有些细节要注意。

核心问题是supervisor和gunicorn都是进程管理器,容易产生冲突。关键要让supervisor只管理gunicorn的主进程,而不是worker进程。

这是我的标准配置:

# gunicorn_config.py
bind = "0.0.0.0:8000"
workers = 4
worker_class = "sync"
daemon = False  # 这个最重要,必须设为False
pidfile = "/tmp/gunicorn.pid"
accesslog = "/var/log/gunicorn/access.log"
errorlog = "/var/log/gunicorn/error.log"
# /etc/supervisor/conf.d/myapp.conf
[program:myapp]
command=/path/to/venv/bin/gunicorn -c gunicorn_config.py myapp:app
directory=/path/to/your/app
user=www-data
autostart=true
autorestart=true
stopasgroup=true  ; 停止整个进程组
killasgroup=true   ; 杀死整个进程组
stderr_logfile=/var/log/supervisor/myapp_err.log
stdout_logfile=/var/log/supervisor/myapp_out.log

几个关键点:

  1. gunicorn配置里daemon = False必须设置,否则supervisor会失去对子进程的控制
  2. supervisor配置里stopasgroupkillasgroup要设为true,这样停止时能清理所有worker进程
  3. 不要用gunicorn的-D参数,让supervisor负责守护进程

重启supervisor:sudo supervisorctl reload

总结:让supervisor做进程管理,gunicorn专注处理请求。

手动杀了呗。。

你的 supervisord 针对 gunicorn 配置了多少个进程?
我也用过 supervisord 作为 gunicorn 的守护进程,没遇到你的问题

#2 需要使用自动化脚本去更新代码

#1 好像没作用,谢谢

#3 文中写了 -w4, 您是怎么关闭 gunicorn 进程的呢

Try using exec gunicorn
搜了下

常识的问一句:为什么要 root 下跑你的程序? python 有用 pyenv 做版本隔离吗?程序依赖有用 venv 隔离吗?有在 dev
下测试过启动脚本吗?

正常情况下是 sudo supervisorctl stop myapp 就可以 kill 掉 gunicorn 进程的,你可以查看下 sudo supervisorctl status 看一下状态。

#9 当 stop myapp 时,状态是 close,但是 gunicorn 进程还在,start myapp 时,状态是 running,然后 gunicorn 进程新增了四个

我觉得要么可能是 supervisor 配置的问题,要么是启动方式的问题,参考下这个 https://medium.com/ymedialabs-innovation/deploy-flask-app-with-nginx-using-gunicorn-and-supervisor-d7a93aa07c18

还有就是你说的多出来的 gunicorn 进程是不是你手动起的,忘记关掉了~~~ ^ _ ^ pkill gunicorn

<br>[program:portal]<br>directory=/var/www/portal<br>command=/home/dev/.pyenv/versions/portal/bin/gunicorn --worker-class=gevent --max-requests 5000 -w 6 -b 127.0.0.1:8100 portal:app<br>loglevel=info<br>autostart=true<br>autorestart=true<br><br>redirect_stderr=true<br>stdout_logfile=/var/log/portal.log<br>user=dev<br>stopsignal=TERM<br><br>stdout_logfile_maxbytes=0<br>stdout_logfile_backups=0<br>

通过 supervisorctl start|stop|restart 控制,启停的关键参数应该是 stopsignal=TERM

其实楼下的就说了,你改一下 stopsignal 应该就可以了,而且 gunicorn 不是有 supervisord 的配置范例吗?

回到顶部