Есть ли способ убить убикорна чисто?

Есть ли способ убить убикорна чисто?

Т.е. я могу набрать на нем ^C, если он запущен на переднем плане на терминале. Это приводит к тому, что процесс uvivorn умирает, а все рабочие процессы очищаются. (Т.е. они уходят.)

С другой стороны, если uvicorn работает в фоновом режиме без терминала, я не могу придумать способ убить его чисто. Кажется, что он игнорирует SIGTERM, SIGINT и SIGHUP. Я могу убить его с помощью SIGKILL (т.е. -9), но тогда рабочие процессы останутся активными, и я должен отследить все рабочие процессы и убить их тоже. Это не идеально.

Я использую uvicorn с CPython 3.7.4, uvivorn версии 0.11.2 и FastAPI 0.46.0 на Red Hat Enterprise Linux Server 7.3 (Maipo).

6 ответов

Это потому что ты бежишь uvicornкак ваш единственный сервер. В uvicorn не является менеджером процессов и, следовательно, не управляет жизненным циклом своих сотрудников. Вот почему они рекомендуют запускать uvicorn с помощью gunicorn+UvicornWorker для производства.

Тем не менее, вы можете убить порожденных рабочих и вызвать его отключение, используя сценарий ниже:

$ kill $(pgrep -P $uvicorn_pid)

Причина, по которой это работает, но не kill на родительском pid, потому что когда вы ^C что-то, сигнал передается через все его порожденные процессы, которые прикреплены к stdin.

      lsof -i :8000

Это проверит процессы, использующие порт:8000. Если вы используете другой порт для fastAPI, измените номер порта. Я использовал postman и python для fastAPI. Поэтому проверьте процесс с помощью python, затем скопируйте PID, обычно 4-5 чисел.

Затем запустите

      kill -9 PID

Где PID - это номер PID, который вы скопировали

В моем случае удалось создать новые процессы, пока pgrep -Pубивал старые, поэтому я решил убить всю группу процессов сразу, как это делает:

      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получает PID родителя uvicorn ... example:app
  • [[ -n "$PID" ]]проверяет, что этот PID не пуст, чтобы избежать дальнейших шагов, когда uvicornне работает
  • ps --no-headers -p $PID -o pgidполучает PGID(идентификатор группы процессов), частью которого является этот PID
  • kill -SIGINTпохоже на вежливый ^C(вы можете использовать kill -9за невежливое мгновенное убийство)
  • --означает, что следующий токен является позиционным аргументом, а не именованным параметром, даже если он начинается с -
  • -${PGID- отрицательное значение позволяет killзнайте, что это PGID, а не PID
  • ${PGID// /}удаляет все пробелы psдобавлен в PGID для выравнивания столбца

Вы можете попробовать запустить команду ниже

      kill -9 $(ps -ef | grep uvicorn  | awk '{print $2}')

или

Создайте псевдоним с помощью команды и продолжайте использовать эту команду. Например:

      alias uvicornprocess="kill -9 $(ps -ef | grep uvicorn  | awk '{print $2}')" 

Вы можете использовать эту команду, чтобы завершить все процессы с именем uvicorn:

      sudo pkill 'uvicorn'

Если вы используете uvicorn в Docker, просто остановите контейнер следующим образом:

      docker ps # to get the CONTAINER ID
docker stop <CONTAINER ID>
Другие вопросы по тегам