如何正确停止Gunicorn

94

我正在使用Django命令python manage.py run_gunicorn 启动gunicorn,如何正确停止gunicorn?

注意:我使用的是半自动化服务器部署工具fabric。因此,手动通过pid杀死进程的方法,例如ps aux | grep gunicorn,不可行。

14个回答

140

查看进程的命令是 ps ax|grep gunicorn,停止gunicorn_django的命令是 pkill gunicorn


7
正如我在问题中提到的,这不是一个选择(自动化部署)。 - j7nn7k
6
@PiyushS.Wanare 执行 kill -9 <pid number> - benjaminz
htop对于查看进程ID以及发送除SIGKILL(-9)之外的各种kill命令非常有用。 - Scott Skiles
6
真的吗?这个答案得到了很高的投票? :o 它将停止运行服务器上的所有gunicorn实例 :/ - vinyll
2
对我来说并不会停止。 - Erol

40

一个选择是使用Supervisor来管理Gunicorn。

然而,我不明白为什么不能通过Fabric杀死进程。 假设你让Gunicorn写入pid文件,那么你可以轻松地在Fabric命令中读取该文件。

像这样的东西应该可以工作:

run("kill `cat /path/to/your/file/gunicorn.pid`")

33
pkill gunicorn
或者
pkill -P1 gunicorn

应该杀死所有正在运行的gunicorn进程。


first one is enough. - Krishnadas PC

19

pkill gunicorn 停止所有gunicorn守护进程。因此,如果您正在使用不同端口运行多个gunicorn实例,请尝试使用此shell脚本。

#!/bin/bash
Port=5000
pid=`ps ax | grep gunicorn | grep $Port | awk '{split($0,a," "); print a[1]}' | head -n 1`
if [ -z "$pid" ]; then
  echo "no gunicorn deamon on port $Port"
else
  kill $pid
  echo "killed gunicorn deamon on port $Port"
fi

ps ax | grep gunicorn | grep $Port 显示特定端口的守护进程。


我有一个类似的情况,我使用了这个命令:lsof "-i:${Port}" | grep gunicorn | cut -d" " -f2 | sort | head -1 - fitorec

17

这是我用过的指令:

pkill -f gunicorn

它将终止任何名称为gunicorn的进程。


1
适用于Mac(zsh)。谢谢! - smm

15

开始:

gunicorn --pid PID_FILE APP:app

停止:

kill $(cat PID_FILE)
gunicorn--pid标志需要一个参数:存储进程ID的文件。服务停止时,该文件也会自动删除。 我为了简单起见使用了PID_FILE,但您应该使用类似于/tmp/MY_APP_PID的文件名。 如果PID文件存在,则表示服务正在运行。 如果没有,那么服务就没有运行。要停止服务,请像提到的那样杀死它。 您还可以想要包括--daemon标志,以便将进程从当前shell中分离。

2
这是一个优雅的解决方案,保证我们不会意外地杀死任何gunicorn进程。谢谢。 - Leogout

5

启动运行在gunicorn上的服务

sudo systemctl enable myproject

sudo systemctl start myproject

或者
sudo systemctl restart myproject

停止运行在Gunicorn上的服务,请执行以下操作:
sudo systemctl stop myproject

要了解有关使用gunicorn托管Python应用程序的更多信息,请参阅此处


2
只有在/etc/systemd/system/中创建了myproject.service文件才能正常工作。请参阅https://freedesktop.org/software/systemd/man/systemd.service.html以了解如何创建systemd服务文件。 - Jaap Joris Vens

3
kill -9 `ps -eo pid,command | grep 'gunicorn.*${moduleName:appName}' | grep -v grep | sort | head -1 | awk '{print $1}'`

ps -eo pid,command命令只会获取进程ID,命令和参数。

grep -v grep可以排除类似于“grep --color=auto xxx”的输出。

sort | head -1进行升序排序并获取第一行。

awk '{print $1}'可以获取PID。

还有一件事情需要注意:你安装的gunicorn在哪里?

Ubuntu 16默认安装了gunicorn,可执行文件是gunicorn3,位于/usr/bin/gunicorn3。如果通过pip安装,它将位于/usr/local/bin/gunicorn。你需要使用 which gunicorngunicorn -v来查找。


3
以上解决方案在进程被杀死时不会删除pid文件。
cat <pid-file> | xargs kill -2

这个解决方案会读取pid文件并发送中断信号。这样可以正确关闭gunicorn,同时pid文件也会被删除。

PID文件可以通过以下方式生成:

gunicorn --pid PID-FILE

或者在配置文件中添加以下内容。
pidfile = "pid_file"

3
如果我们执行以下命令:
pkill gunicorn

我们停止所有gunicorn服务,在这种情况下,要启动gunicorn,我们只需要停止与服务相关的父进程,该父进程负责侦听gunicorn将要执行的端口。

以下脚本搜索所述进程(pid),如果存在,则终止该进程:

#!/bin/bash
# ---------------------
stop_unicorn_on_port() {
  pid=$(lsof -w -t -i "TCP:${1}" | head -1)
  if [ -z "${pid}" ]; then
    echo " no service deamon on port ${1}"
  else
    kill -9 "${pid}"
    echo " killed service deamon(${pid}) on port ${1}"
  fi
}
# Example/Testing
stop_unicorn_on_port 5000
stop_unicorn_on_port 5001
stop_unicorn_on_port 5002

更多信息请查看:man lsoft

  • -t选项指定lsof应该生成简洁的输出,仅包含进程标识符和没有标题 - 例如,这样输出可以被管道传递到kill(1)中。 -t选项选择-w选项。

  • -i选项选择列出所有Internet地址与i指定的地址匹配的文件。如果未指定地址,则此选项选择列出所有Internet和x.25(HP-UX)网络文件...

Here are some sample addresses:

                     -i6 - IPv6 only
                     TCP:25 - TCP and port 25
                     @1.2.3.4 - Internet IPv4 host address 1.2.3.4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接