我正在使用httpd -k graceful
动态地重新加载服务器,并且在python代码中使用time.sleep发出了缓慢的请求,并且我希望在重新加载apache之后不会中断活动请求。但是确实如此。
所以我尝试了使用CGI的简单python服务器,它运行良好。然后,我使用apache进程(仅指定WSGIScriptAlias
)尝试了mod_wsgi,它也很好用。
所以我发现问题出在我最初使用的WSGIDaemonProcess
上。
然后在mod_wsgi文档中,我发现了这一点:
eviction-timeout = sss
向守护进程发送正常重启信号(通常为SIGUSR1)以重启进程时,此超时控制进程在到达空闲状态且没有活动请求时将等待多少秒,同时仍接受新请求,并且关闭。
如果未指定此超时,则将使用宽限超时的值。如果未指定graceful-timeout,则发送的重启重启信号将立即发生,并在关机超时到期时强制终止进程(如有必要)。
当我以为自己会找到原因时,我发现这些参数(我也尝试过graceful-timeout
)根本没有用。正常的重载仍然中断了请求。那为什么呢?
我使用的是apache 2.4.6
,mpm模式为prefork
。然后modwsgi 4.6.5
,我自己编译并用旧版本的mod_wsgi.so替换了它。
答案 0 :(得分:0)
来自GrahamDumpleton @ Github的答案:(https://github.com/GrahamDumpleton/mod_wsgi/issues/383)
您所看到的完全符合预期。 Apache不会将正常的重启信号传递给托管子进程,而只会将它们传递给自己的子工作进程。对于托管进程,它将发送SIGTERM
,如果它们没有关闭,将在3或5秒钟(不记得确切的时间)后残酷地杀死它们。没有其他办法了。这是对Apache的限制。
驱逐超时因此仅适用于文档所说的直接向“守护进程”直接发送正常重启信号的时间。也就是说,从整体上正常重启Apache不会执行任何操作,但是会将正常重启信号发送到守护进程自身的pid。
因此,此行为很重要的唯一解决方案是,确保对display-name
指令使用WSGIDaemonProcess
选项,以便守护进程与Apache进程相比具有唯一的名称,然后仅直接向其发送信号。 / p>
通常这仅会成为问题,因为某些Linux系统完全忽略了Apache具有完美的日志文件轮换系统的事实,而是通过每天一次重命名日志文件然后尝试正常重启来进行外部日志文件轮换。人们会看到意外的请求中断问题。在这种情况下,如果重要的话,您应该使用Apache自己的日志文件轮换机制,并且不要依赖外部日志文件轮换系统。