停止在一个schroot会议中运行的Gun​​icorn

时间:2014-11-30 11:57:40

标签: gunicorn supervisord schroot

我正在通过主管在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托管流程?

2 个答案:

答案 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帮助程序启动schroot gunicorn进程(来自主管分发,/ usr / bin / pidproxy)
  2. 将gunicorn进程的PID写入文件(通常通过修改应用程序启动)
  3. 尽可能正确使用exec。
  4. 广告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实际杀死它。