python 有没有办法干净利落地杀死uvicorn?

xurqigkl  于 2022-11-21  发布在  Python
关注(0)|答案(3)|浏览(329)

有没有办法干净利落地杀死uvicorn?
也就是说,如果uvivorn进程在终端的前台运行,我可以在它上面输入^C,这会导致uvivorn进程死亡,所有的工作进程都被清理掉(也就是说,它们都消失了)。
另一方面,如果uvicorn在后台运行而没有终端,那么我就找不到一种方法来彻底地杀死它。它似乎忽略了SIGTERM、SIGINT和SIGHUP。我可以用SIGKILL(即-9)杀死它,但这样工作进程仍然活着,我必须跟踪所有的工作进程并杀死它们。这并不理想。
我在红帽企业Linux服务器7.3(Maipo)上使用的是带有CPython 3.7.4、uvivorn版本0.11.2和FastAPI 0.46.0的uvicorn。

nafvub8i

nafvub8i1#

这是因为您正在运行uvicorn作为您唯一的服务器。uvicorn不是一个进程管理器,因此,它不管理其worker生命周期。这就是为什么他们建议使用gunicorn+UvicornWorker运行uvicorn用于生产。
也就是说,您可以使用下面的脚本杀死衍生的工作线程并触发它的关闭:

$ kill $(pgrep -P $uvicorn_pid)

之所以这样做而kill在父pid上不起作用,是因为当您执行^C时,信号会在所有附加到stdin的派生进程中传输。

t1rydlwq

t1rydlwq2#

lsof -i :8000

这将检查进程使用端口:8000。如果你使用不同的端口为fastAPI,然后改变端口号。我用 Postman 和python为fastAPI。所以检查进程与python,然后复制PID通常4-5个数字。
然后运行

kill -9 PID

其中PID是您复制的PID编号

yhxst69z

yhxst69z3#

在我的例子中,uvicorn设法在pgrep -P杀死旧进程的同时生成新进程,所以我决定一次杀死整个进程组,就像^C所做的那样:

PID="$(pgrep -f example:app)"
if [[ -n "$PID" ]]
then
    PGID="$(ps --no-headers -p $PID -o pgid)"
    kill -SIGINT -- -${PGID// /}
fi

每一行都解释道:

  • pgrep -f example:app获取父级uvicorn ... example:app的PID
  • [[ -n "$PID" ]]检查此PID是否为空,以避免在uvicorn未运行时执行进一步的步骤
  • ps --no-headers -p $PID -o pgid获取此PID所属的PGID(进程组ID)
  • kill -SIGINT类似于礼貌的^C(您可以将kill -9用于非礼貌的即时kill)
  • --表示下一个标记是位置参数,而不是命名选项,即使它以-开头
  • -${PGID-负值使kill知道它是PGID,而不是PID
  • ${PGID// /}删除添加到PGID中以对齐列的所有空格ps

相关问题