将SIGTERM发送到Apache父进程,现在就是这样了。在
发生的情况是,当Apache父进程接收到SIGTERM时,它又将SIGTERM发送给它的所有子工作进程,如果使用守护程序模式,它也会发送到托管mod乩wsgi守护进程。在子进程被强制关闭之前,这些子进程将停止接受新请求,并在3秒钟内完成现有请求。在
因此,SIGTERM的默认行为是允许一点时间来完成请求,但是长时间运行的请求将不允许延迟服务器完全关闭。它等待子进程关闭的时间是不可配置的,固定为3秒。在
您可以发送一个SIGWINCH信号,而不是SIGTERM。这将导致Apache优雅地停止,但这有问题。在
在SIGWINCH的情况下,Apache将再次向其子工作进程发送SIGTERM,但它不会在3秒钟后强制终止进程,而是允许它们运行,直到至少任何活动请求完成为止。在
一个问题是没有故障保险。如果这些请求从未完成,就没有超时,据我所知,它将强制关闭子工作进程。因此,您的服务器可能会在关闭时挂起。在
第二个问题是,Apache仍然会在3秒后强制关闭托管mod wsgi守护进程,并且没有(或者上次没有看到)一种方法来覆盖Apache管理这些进程的方式,从而能够更优雅地关闭托管守护进程。所以优雅的停止信号在使用守护程序模式时不会改变任何东西。在
最接近完美停止的是前端路由层,将新流量从Apache实例中转移出去。然后通过某种机制在运行Apache的主机中触发一个脚本,该脚本向mod wsgi守护进程发送一个SIGUSR2。假设您已经将守护进程组上的graceful-timeout选项设置为某种适当的故障保护,那么当所有活动请求完成时,这将导致守护进程退出。如果超时过期,那么它将进入正常的进程关闭序列,即不接受来自Apache子工作进程的新请求,shutdown-timeout(默认为5秒)激发后,如果请求仍未完成,则进程将被强制关闭。在
在本例中,它实际上并没有关闭进程,而是导致进程退出,这将导致它们被替换,因为我们并没有告诉整个Apache停止,而只是告诉mod unwsgi守护进程优雅地重新启动。在这种情况下,除非您监视守护进程集并知道它们何时全部重新启动,否则无法清楚地表明它们都已完成,然后可以关闭整个Apache实例。在
因此,这样做有点麻烦,而且任何服务器都很难以一种良好的通用方式来完成这项工作,因为什么是合适的还取决于托管应用程序及其需求。在
问题是你是否真的需要做这些。无论如何,请求都将不可避免地失败,用户必须处理这个问题,因此在重新启动时中断少数请求并不是什么大问题。应用程序有什么特别之处,您需要设置更高的标准并尝试确保零请求被中断?在