如何从mod_wsgi中正常关闭应用程序 [英] How to do graceful application shutdown from mod_wsgi

查看:123
本文介绍了如何从mod_wsgi中正常关闭应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我有一个Flask应用程序,该应用程序已在Flask的内置服务器上运行,并准备将其移至生产环境.该应用程序管理多个子进程.至此,我一直在使用信号处理正常关机.特别是,我使用的一种关机模式是向烧瓶服务器发送SIGHUP,使应用程序将该信号传播到其子进程(以便它们可以正常关机),然后让应用程序进程关机.

So I have a Flask application which I've been running on Flask's built-in server, and am ready to move it to production. This application manages several child processes. To this point, I've been handling graceful shutdown using signals. In particular, one shutdown mode I've used is to have sending a SIGHUP to the flask server cause the application to propagate that signal to its children (so they can gracefully shutdown), and then let the application process shutdown.

在生产中,我们计划使用mod_wsgi.我已经读过 wsgi应用程序确实不应该处理信号.

In production, we're planning on using mod_wsgi. I've read that wsgi applications really shouldn't be handling signals.

所以我的问题是,如何通过此设置实现以下行为?

So my question is, how should I achieve the following behavior with this setup?:

  • 当apache收到SIGTERM时,它将在终止它们之前通知wsgi守护程序
  • wsgi守护程序有机会在关闭之前自行进行一些清理

推荐答案

SIGTERM发送到Apache父进程,这就是现在发生的事情.

Send SIGTERM to the Apache parent process and that is what sort of happens now.

发生的事情是,当Apache父进程接收到SIGTERM时,它将依次将SIGTERM发送到其所有子工作进程以及使用守护程序模式的托管mod_wsgi守护进程.这些子进程将停止接受新的请求,并且在强制关闭子进程之前,将有3秒钟的时间来完成现有请求.

What happens is that when the Apache parent process receives SIGTERM, it in turn sends SIGTERM to all its child worker processes, as well as to the managed mod_wsgi daemon processes if using daemon mode. Those sub process will stop accepting new requests and will be given up to 3 seconds to complete existing requests, before the sub processes are forcibly shutdown.

因此,SIGTERM的默认行为是允许一些时间来完成请求,但是长时间运行的请求将不允许阻止服务器完全关闭.等待子进程关闭的时间是无法配置的,固定为3秒.

So the default behaviour of SIGTERM is to allow a bit of time to complete requests, but long running requests will not be allowed to hold up complete server shutdown. How long it does wait for sub processes to shutdown is not configurable and is fixed at 3 seconds.

您可以发送SIGWINCH信号,而不是SIGTERM.这将导致Apache正常停止,但这会带来问题.

Instead of SIGTERM, you can send a SIGWINCH signal instead. This will cause Apache to do a graceful stop, but this has issues.

SIGWINCH情况下发生的事情是,Apache将再次将SIGTERM发送到其子工作进程,但不是强制终止进程3秒钟,而是允许它们运行直到至少任何一个进程.活动请求已完成.

What happens in the case of SIGWINCH, is that Apache will send SIGTERM to its child worker process again, but instead of forcibly killing off the processes after 3 seconds, it will allow them to run until at least any active requests have completed.

与此有关的一个问题是没有故障保护功能.如果这些请求从未完成,那么我就知道没有超时将导致子工作进程被强制关闭.结果,您的服务器可能最终会在关机时挂起.

A problem with this is that there is no fail safe. If those requests never finish, there is no timeout that I know of which will see the child worker processes forcibly shutdown. As a result, your server could end up hanging on shutdown.

第二个问题是,Apache仍将在3秒后强行杀死托管的mod_wsgi守护进程,并且没有(或上次没有看过)一种替代Apache如何管理这些进程的方法,以实现更多功能.在托管守护进程上正常关闭.因此,在使用守护程序模式时,优美的停止信号不会改变任何内容.

A second issue is that Apache will still forcibly kill off the managed mod_wsgi daemon processes after 3 seconds and there isn't (or wasn't last time looked) a way to override how Apache manages those processes, to enable a more graceful shutdown on the managed daemon processes. So graceful stop signal doesn't change anything when using daemon mode.

您可以最方便地在前端路由层中进行操作,将新流量从Apache实例转移出去.然后通过运行Apache的主机中的某种机制触发器,将脚本发送SIGUSR2到mod_wsgi守护进程.假设已将守护进程组中的graceful-timeout选项设置为足够的故障保险,这将导致守护进程在所有活动请求完成后退出.如果超时到期,则它将进入其正常进程关闭顺序,即不接受来自Apache子工作进程的新请求,并且在触发shutdown-timeout(默认5秒)后,如果请求仍未完成,则该进程将被强制关闭

The closest you can get to a graceful stop, is in a front end routing layer, divert new traffic away from the Apache instance. Then through some mechanism trigger within the host running Apache a script which sends a SIGUSR2 to the mod_wsgi daemon processes. Presuming you have set graceful-timeout option on the daemon process group to some adequate failsafe, this will result in the daemon processes exiting if all active requests finish. If the timeout expires, then it will go into its normal process shutdown sequence of not accept new requests from the Apache child worker processes and after the shutdown-timeout (default 5 seconds) fires, if requests still not complete, the process is forcibly shutdown.

在这种情况下,实际上并没有关闭进程,而是导致它们退出,这将导致它们被替换,因为我们不是在告诉整个Apache停止运行,而是在告诉mod_wsgi守护进程正常重启.在这种情况下,除非您监视守护进程集并知道它们何时全部重新启动,否则您没有明确的指示它们已经完成,然后可以关闭整个Apache实例.

In this case, it isn't actually shutting down the processes, but causing them to exit, which will result in them being replaced as we aren't telling the whole Apache to stop, but just telling the mod_wsgi daemon processes to do a graceful restart. In this situation, unless you monitor the set of daemon processes and know when they have all restarted, you don't have a clear indication that they are all done and can then shutdown the whole Apache instance.

因此,这样做有点麻烦,而且任何服务器都很难以一种很好的通用方式来执行此操作,因为真正合适的方法还取决于托管应用程序及其要求.

So it is a little bit fiddly to do and it is hard for any server to do this in a nice generic way as what is appropriate really also depends on the hosted application and what its requirements are.

问题是您是否真的需要达到这些长度.无论如何,请求都不可避免地会失败,用户必须对此进行处理,因此在重新启动时中断少数请求通常不是什么大问题.该应用程序有什么特别之处,您需要设置一个更高的标准并尝试确保零个请求被中断?

The question is if you really need to go to these lengths. Requests will inevitably fail anyway and users have to deal with that, so often interruption of a handful of requests on a restart is not a big deal. What is so special about the application that you need to set a higher bar and attempt to ensure that zero requests are interrupted?

这篇关于如何从mod_wsgi中正常关闭应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆