我正在通过主管在schroot会话中运行一个Gunicorn服务器。我的问题是,当使用“supervisorctl stop”停止服务时,服务没有完全停止。
这是控制我的服务器的脚本(简化),它在前台运行gunicorn:
# gunicorn.sh
schroot -c gunicorn -r -- bash -c "gunicorn --workers=1 myapp.wsgi:application"
这是我的主管配置来运行这个脚本:
[program:gunicorn]
command=/home/test/gunicorn.sh
stderr_logfile=/var/log/gunicorn.err.log
stdout_logfile=/var/log/gunicorn.out.log
当我通过“supervisorctl start”启动服务时,我的进程树如下所示:
supervisord(7175)---gunicorn.sh(8061)---schroot(8067)---gunicorn(8068)---gunicorn(8073)---{gunicorn}(8078)
现在当我使用“supervisorctl stop”停止服务时,相应的主管进程及其直接子进程gunicorn.sh将被终止。 但schroot过程本身仍然存在,现在是init过程的孩子:
schroot(8067)---gunicorn(8068)---gunicorn(8073)---{gunicorn}(8078)
这整个行为似乎与schroot和gunicorn的工作方式有关。
如何让主管正确停止我的schroot托管流程?
答案 0 :(得分:0)
不得不与执行官一起开枪:
# gunicorn.sh
exec schroot -c gunicorn -r -- bash -c "gunicorn --workers=1 myapp.wsgi:application"
答案 1 :(得分:0)
我今天解决了完全相同的问题 - 但是接受的解决方案无效。引用了同样的问题,例如here。
使用管理程序运行程序通常要求您执行的任何操作都是使用exec()系统调用完成的 - 因为它将原始进程替换为自身,留下PID(对于管理员来说很重要)来管理(不需要从中删除)当然是终点站。
在schroot会议中开始使用gunicorn总是产生两个过程 - schroot - 由主管引用 - 和gunicorn主人(工人并不重要)。
在supervisor中调用stop只会杀死schroot并让gunicorn master转移到init(PID = 1),让它实际运行。
如果没有chroot,最简单的方法就是“执行枪支/无论什么/&#39 ;.
解决方法我发现似乎没问题就是这样:
广告1.使用pidproxy
[program:xxx]
command = pidproxy /path/to/pid/file /path/to/xxx
广告2.使用任何方法将pid写入文件。我在应用启动期间使用了以下代码段:
pid_file = os.path.join(conf.data_dir, "eventaid.pid")
with open(pid_file, "w") as fout:
fout.write(str(os.getpid()))
广告3.在脚本/ path / to / xxx
中使用exec# activate venv
. $HOME/.virtualenvs/python3-xxx/bin/activate
# start within schroot
exec schroot -c jessie -- sh -c "exec gunicorn <whatever>"
现在从主管内部发送SIGTERM / SIGKILL / ...实际上会将SIGTERM / SIGKILL / ...发送到pidproxy,pidproxy会将信号转发给gunicorn PID实际杀死它。