<p>werkzeug.serving.run_simple неправильно обрабатывает SIGTERM</p>

Созданный на 9 мая 2011  ·  11Комментарии  ·  Источник: pallets/werkzeug

Когда процесс получает SIGTERM , он должен завершиться и завершиться, выполнив как можно меньше операций и ничего не печатая.

Процесс werkzeug.serving.run_simple получающий SIGTERM обычно приводит к коду возврата 141 (симптом необработанного / неправильно обработанного SIGPIPE ), а при использовании перезагрузчика процесс становится зомби (он имеет быть убитым вручную, так как порт остается связанным).

Добавление обработчика сигнала для SIGTERM который просто вызывает sys.exit(0) , достаточно, чтобы исправить проблему (в том смысле, что больше нет неправильного поведения процесса), но я не уверен, что это действительно правильное исправление.

Самый полезный комментарий

Получил также эту ошибку, в моем случае docker stop отправлял SIGTERM на сервер с werkzeug (moto), но сервер проигнорировал его, а затем докер убил его с помощью SIGKILL результате в ненулевой код выхода.

Обходной путь заключался в том, чтобы указать SIGINT (Ctrl + C) в качестве предпочтительного сигнала остановки в Dockerfile ( STOPSIGNAL SIGINT ), после чего контейнеры полностью отключились.

Все 11 Комментарий

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

В какой версии это исправление? Это все еще проблема в Flask 0.8.

Это все еще проблема, это довольно раздражает при использовании Flask с IDE - всякий раз, когда вы прекращаете отладку, процесс сохраняется и продолжает обслуживать запросы.

Я снова открываю эту проблему, поскольку она, кажется, сохраняется, см. Следующее обсуждение сегодня в IRC.

20:20 < mcdonc> can somebody fix flask's reloader so when you send the process a sigint it actually stops the child process
20:20 < untitaker> mcdonc: it seems to work for me
20:21 < untitaker> mcdonc: it used to cause problems but for me it's fixed in latest master
20:21 < mcdonc> ah good.  i just got some number of complaints from people who run it under supervisor.
20:22 < untitaker> mcdonc: you are talking about the one from the Py3 port?
20:22 < untitaker> released versions should work properly
20:22 < mcdonc> no.. i am talking about.. well.. yes, i dont actually know what i'm talking about ;-)  i dont use it, i just get people telling me they need to send a stop signal to the entire process group instead of to the process to make sure its killed.
20:23 < mcdonc> this is not recent.. for the last year or so
20:23 < mcdonc> why people run the reloader under supervisor (presumably in production) i cannot fathom
20:23 < mcdonc> but they do
20:24 < Alex_Gaynor> mcdonc: I've toyed with using supervisord in dev, FWIW
20:24 < Alex_Gaynor> mcdonc: for cases where you don't just have web proc, you've also got background daemons and such, it could be nice
[...]
20:32 < DasIch> untitaker: the supervisor issue is independent from the threading/thread issue
20:32 < untitaker> DasIch: ah okay
20:32 < untitaker> didn't know that
20:32 < untitaker> DasIch: is the reloader behaving weird in supervisor?
20:33 < DasIch> untitaker: I guess what happens if you run the reloader in supervisor is that supervisor kill the reloading process but that doesn't kill the process started by the reloader
20:34 < untitaker> DasIch: couldn't one write a wrapper shell script that kills both?
20:34 < untitaker> at least for now
20:34 < DasIch> untitaker: I think you shouldn't use the reloader in production
20:35 < untitaker> well yeah
20:35 < asdf`> (supervisord has a 'kill as group' thing)
20:35 < DasIch> right there is that as well
20:35 < asdf`> (it even mentions the werkzeug reloader in the docs paragraph about it!)
20:36 < mcdonc> yes i put it there
20:37 < asdf`> (then you might want to fix it, because AFAIR it actually says 'flask', while the reloader is part of werkzeug. But i admit 'flask' is something more people will know)
20:37 < mcdonc> nobody reads docs anyway ;)
20:38 < DasIch> I just wanted to mention I don't care unless someone creates an issue with a valid use case for that but apparently this seems to be it https://github.com/mitsuhiko/werkzeug/issues/58
20:38 < mcdonc> like alex said, it's not entirely crazy to want to use the reloader under supervisor in dev, esp. if your app is reliant on other processes being started
20:39 < mcdonc> i actually dont run my own apps under supervisor, but that's because i don't use a reloader, i just press ctrl-c.. because i'm a savage
20:40 < DasIch> I do use the reloader but I tend to save so often with bad syntax that I end up restarting manually all the time

Думаю, это все еще актуально.

Выполнение os.kill(parent_id, signal.SIGTERM) не убивает дочерние процессы.

Я тоже столкнулся с этой проблемой при переработке набора тестов для werkzeug.serving . Я работал над этим, убивая всю группу процессов: https://github.com/mitsuhiko/werkzeug/blob/a00377315bbf02ec48fdad22c6bb08433fc1e9c1/tests/conftest.py#L158

Я столкнулся с той же проблемой во Flask в режиме отладки (use_debugger = True). Однако я вижу код возврата 0 для «родительского» процесса. Без включенного режима отладки SIGTERM работает нормально, и процесс завершается с кодом 143. Python 2.7.5.

Получил также эту ошибку, в моем случае docker stop отправлял SIGTERM на сервер с werkzeug (moto), но сервер проигнорировал его, а затем докер убил его с помощью SIGKILL результате в ненулевой код выхода.

Обходной путь заключался в том, чтобы указать SIGINT (Ctrl + C) в качестве предпочтительного сигнала остановки в Dockerfile ( STOPSIGNAL SIGINT ), после чего контейнеры полностью отключились.

У меня такая же проблема при запуске приложения Flask внутри Docker; однако STOPSIGNAL SIGINT по-прежнему недостаточно, чтобы остановить контейнер. Мне нужно использовать SIGKILL .

Я не могу воссоздать проблему. Я пробовал это с официальным контейнером Python с тегами 2.7 и 3.7. Я использовал следующий Dockerfile:

FROM python:2.7

WORKDIR /usr/src/app

RUN pip install click \
                werkzeug \
                sqlalchemy \
                jinja2

COPY . .

RUN python manage-shorty.py initdb

ENTRYPOINT ["python"]

CMD ["manage-shorty.py", "runserver"]

И построил контейнер из Dockerfile в каталоге examples с помощью команды:

 docker build -t werkzeug-examples .

Затем я бы запустил контейнер в интерактивном режиме и отменил бы с помощью:

$ docker run -it --name werkzeug-example werkzeug-examples
 * Running on http://localhost:5000/ (Press CTRL+C to quit)
 * Restarting with stat
^C

Запуск docker ps показал, что он завершился с 0 :

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS                      PORTS               NAMES
8c708ea4ef77        werkzeug-examples   "python manage-short…"   About a minute ago   Exited (0) 58 seconds ago                       werkzeug-example

Запуск контейнера и остановка с помощью docker stop werkzeug-example также завершается с помощью 0 .

Вот результат версии Docker на компьютере, на котором я выполнил эти команды:

Client: Docker Engine - Community
 Version:           18.09.2
 API version:       1.39
 Go version:        go1.10.8
 Git commit:        6247962
 Built:             Sun Feb 10 04:12:39 2019
 OS/Arch:           darwin/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.2
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.6
  Git commit:       6247962
  Built:            Sun Feb 10 04:13:06 2019
  OS/Arch:          linux/amd64
  Experimental:     false

Можете ли вы привести пример, который может воспроизвести проблему, с которой вы столкнулись?

Пока мы не получим воспроизводимый сценарий, я закрою его, поскольку он не может быть воспроизведен в последней версии Docker и Werkzeug.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

Nessphoro picture Nessphoro  ·  6Комментарии

taion picture taion  ·  7Комментарии

SimonSapin picture SimonSapin  ·  12Комментарии

miki725 picture miki725  ·  10Комментарии

ngaya-ll picture ngaya-ll  ·  8Комментарии