<p>werkzeug.serving.run_simple无法正确处理SIGTERM</p>

创建于 2011-05-09  ·  11评论  ·  资料来源: pallets/werkzeug

当进程接收到SIGTERM ,它应关闭并退出,并进行尽可能少的操作且不打印任何内容。

werkzeug.serving.run_simple进程收到SIGTERM的返回码通常为141(未处理/错误处理的SIGPIPE症状),并且在使用重新加载程序时,进程变为僵尸(由于端口保持绑定状态,需要手动杀死)。

SIGTERM添加一个仅调用sys.exit(0)的信号处理程序就足以解决该问题(因为不会再有该过程的不当行为了),但是我不确定这实际上是正确的解决方法。

最有用的评论

也遇到了这个错误,在我的情况下, docker stop正在将SIGTERM发送到由werkzeug驱动的服务器(moto),但是服务器忽略了,然后docker用SIGKILL杀死了它变成非零的退出代码。

解决方法是在容器干净关闭之后,将SIGINT (Ctrl + C)指定为Dockerfile( STOPSIGNAL SIGINT )中的首选停止信号。

所有11条评论

现在,当使用reloader运行时,我绑定了一个信号处理程序。 希望能有所帮助。

此修复程序是什么版本的? 在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 :

我在使用调试模式(use_debugger = True)的Flask中遇到了同样的问题。 但是,我在“父”进程上看到的返回码为0。 如果未启用调试模式,则SIGTERM可以正常工作,并且该过程以代码143退出。Python 2.7.5。

也遇到了这个错误,在我的情况下, docker stop正在将SIGTERM发送到由werkzeug驱动的服务器(moto),但是服务器忽略了,然后docker用SIGKILL杀死了它变成非零的退出代码。

解决方法是在容器干净关闭之后,将SIGINT (Ctrl + C)指定为Dockerfile( STOPSIGNAL SIGINT )中的首选停止信号。

在Docker中运行Flask应用程序时,我遇到了同样的问题; 但是, STOPSIGNAL SIGINT仍然不足以停止容器。 我必须使用SIGKILL

我无法重现该问题。 我已经使用带有2.7和3.7标签的官方Python容器尝试了此操作。 我使用了以下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评论

KangOl picture KangOl  ·  16评论

alexgurrola picture alexgurrola  ·  5评论

mrx23dot picture mrx23dot  ·  6评论

lepture picture lepture  ·  6评论