【问题标题】:Stopping Gunicorn running in a schroot session停止 Gunicorn 在 schroot 会话中运行
【发布时间】:2014-11-30 11:57:39
【问题描述】:

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

【问题讨论】:

    标签: gunicorn supervisord schroot


    【解决方案1】:

    必须用 exec 启动 gunicorn:

    # gunicorn.sh
    exec schroot -c gunicorn -r -- bash -c "gunicorn --workers=1 myapp.wsgi:application"
    

    【讨论】:

      【解决方案2】:

      我今天已经解决了完全相同的问题 - 但公认的解决方案不起作用。引用了相同的问题,例如 here

      使用主管运行程序通常要求您执行的任何操作都使用 exec() 系统调用完成 - 因为它用自己替换原始进程,将 PID(这很重要)留给主管管理(无需脱离当然是终端)。

      在 schroot 会话中启动 gunicorn 总是会产生两个进程 - 由主管引用的 schroot - 和 gunicorn master(工人并不重要)。

      在主管中调用 stop 只会杀死 schroot 并使 gunicorn master 迁移到 init (PID=1) 使其实际运行。

      没有 chroot,最简单的方法就是 'exec gunicorn /whatever/'。

      我发现似乎没问题的解决方法是这样的:

      1. 使用 pidproxy 帮助程序启动 schroot gunicorn 进程(来自主管分发,/usr/bin/pidproxy)
      2. 将 gunicorn 进程的 PID 写入文件(通常通过修改应用程序启动)
      3. 尽可能正确使用 exec。

      广告 1. 使用 pidproxy

      [program:xxx]
      command = pidproxy /path/to/pid/file /path/to/xxx
      

      广告 2. 使用任何方法将 pid 写入文件。我刚刚在我的应用启动期间使用了以下代码 sn-p:

      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 实际杀死它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-02
        • 1970-01-01
        • 1970-01-01
        • 2015-10-02
        • 2016-03-29
        • 1970-01-01
        • 2021-05-23
        • 2015-12-10
        相关资源
        最近更新 更多