19

有没有办法干净地杀死uvicorn?

即,如果它在终端的前台运行,我可以在其中键入 ^C。这会导致 uvivorn 进程终止,并清理所有工作进程。(即,他们走了。)

另一方面,如果 uvicorn 在没有终端的情况下在后台运行,那么我想不出一种方法来干净地杀死它。它似乎忽略了 SIGTERM、SIGINT 和 SIGHUP。我可以用 SIGKILL(即 -9)杀死它,但是工作进程仍然活着,我必须跟踪所有工作进程并将它们也杀死。这并不理想。

我在 Red Hat Enterprise Linux Server 7.3 (Maipo) 上将 uvicorn 与 CPython 3.7.4、uvivorn 版本 0.11.2 和 FastAPI 0.46.0 一起使用。

4

2 回答 2

11

那是因为您uvicorn作为唯一的服务器运行。Theuvicorn 不是流程管理器,因此,它不管理它的工人生命周期。这就是为什么他们建议使用 gunicorn+UvicornWorker 运行 uvicorn进行生产。

也就是说,您可以使用以下脚本杀死生成的工作人员并触发其关闭:

$ kill $(pgrep -P $uvicorn_pid)

这有效但kill在父 pid 上无效的原因是,当您执行^C某些操作时,信号会在所有附加到stdin.

于 2020-09-29T23:58:53.447 回答
0

在我的情况下,在杀死旧进程的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获取父进程的 PIDuvicorn ... example:app
  • [[ -n "$PID" ]]检查此 PID 是否为空,以避免在uvicorn未运行时执行进一步的步骤
  • ps --no-headers -p $PID -o pgid获取此 PID 所属的 PGID(进程组 ID)
  • kill -SIGINT类似于礼貌^C(您可以kill -9用于非礼貌的即时杀戮)
  • --表示下一个标记是位置参数,而不是命名选项,即使它以-
  • -${PGID- 负值让我们kill知道它是 PGID,而不是 PID
  • ${PGID// /}ps删除添加到 PGID 以对齐列的所有空格
于 2022-02-08T15:15:43.933 回答