mod_wsgi DaemonProcess 模式在 httpd 优雅重新加载时出现问题
mod_wsgi DaemonProcess mode gets problem with httpd graceful reload
我正在使用 httpd -k graceful
动态重新加载我的服务器,我在 python 代码中使用 time.sleep 来发出缓慢的请求,我预计活动请求不会在 apache 重新加载后被中断。但确实如此。
所以我尝试了一个使用 CGI 的简单 python 服务器,它运行良好。然后我尝试 mod_wsgi 使用 apache 进程(仅指定 WSGIScriptAlias
),它也运行良好。
所以我发现问题出在我原来使用的WSGIDaemonProcess
然后在 mod_wsgi 文档中我发现了这个:
eviction-timeout=sss
When a daemon process is sent the graceful restart signal, usually SIGUSR1, to restart a process, this timeout controls how many seconds the process will wait, while still accepting new requests, before it reaches an idle state with no active requests and shutdown.
If this timeout is not specified, then the value of the graceful-timeout will instead be used. If the graceful-timeout is not specified, then the restart when sent the graceful restart signal will instead happen immediately, with the process being forcibly killed, if necessary, when the shutdown timeout has expired.
当我以为我要找到原因时,我发现这些参数(我也尝试了 graceful-timeout
)在 all.The 请求仍然被优雅重新加载中断.那为什么?
我正在使用 apache 2.4.6
,采用 mpm 模式 prefork
。 modwsgi 4.6.5
,我自己编译的,用它替换了我的旧版本mod_wsgi.so。
来自 GrahamDumpleton@Github 的回答:(https://github.com/GrahamDumpleton/mod_wsgi/issues/383)
您所看到的与预期的完全一样。 Apache 不会将优雅的重启信号传递给托管子进程,它只会将它们传递给自己的子工作进程。对于托管进程,它将发送一个 SIGTERM
并且如果它们没有关闭,它会在 3 或 5 秒后(不记得确切的时间)残忍地杀死它们。没有其他办法了。这是 Apache 的限制。
因此,逐出超时仅适用于文档所说的 'daemon process' 直接发送正常重启信号的情况。也就是说,作为一个整体优雅地重新启动 Apache 不会做任何事情,但会向守护进程本身的 pid 发送优雅的重启信号。
因此,如果此行为很重要,唯一的解决方案是确保您使用 display-name
选项到 WSGIDaemonProcess
指令,以便守护进程与 Apache 进程相比具有唯一的命名,然后仅直接向它们发送信号.
通常这只会成为一个问题,因为一些 Linux 系统完全忽略了 Apache 具有非常好的日志文件轮换系统这一事实,而是通过每天重命名日志文件一次然后尝试进行外部日志文件轮换优雅的重启。人们会看到他们不期望的中断请求的问题。在这种情况下,如果它很重要,您应该使用 Apache 自己的日志文件轮换机制,而不是依赖于外部日志文件轮换系统。
我正在使用 httpd -k graceful
动态重新加载我的服务器,我在 python 代码中使用 time.sleep 来发出缓慢的请求,我预计活动请求不会在 apache 重新加载后被中断。但确实如此。
所以我尝试了一个使用 CGI 的简单 python 服务器,它运行良好。然后我尝试 mod_wsgi 使用 apache 进程(仅指定 WSGIScriptAlias
),它也运行良好。
所以我发现问题出在我原来使用的WSGIDaemonProcess
然后在 mod_wsgi 文档中我发现了这个:
eviction-timeout=sss
When a daemon process is sent the graceful restart signal, usually SIGUSR1, to restart a process, this timeout controls how many seconds the process will wait, while still accepting new requests, before it reaches an idle state with no active requests and shutdown.
If this timeout is not specified, then the value of the graceful-timeout will instead be used. If the graceful-timeout is not specified, then the restart when sent the graceful restart signal will instead happen immediately, with the process being forcibly killed, if necessary, when the shutdown timeout has expired.
当我以为我要找到原因时,我发现这些参数(我也尝试了 graceful-timeout
)在 all.The 请求仍然被优雅重新加载中断.那为什么?
我正在使用 apache 2.4.6
,采用 mpm 模式 prefork
。 modwsgi 4.6.5
,我自己编译的,用它替换了我的旧版本mod_wsgi.so。
来自 GrahamDumpleton@Github 的回答:(https://github.com/GrahamDumpleton/mod_wsgi/issues/383)
您所看到的与预期的完全一样。 Apache 不会将优雅的重启信号传递给托管子进程,它只会将它们传递给自己的子工作进程。对于托管进程,它将发送一个 SIGTERM
并且如果它们没有关闭,它会在 3 或 5 秒后(不记得确切的时间)残忍地杀死它们。没有其他办法了。这是 Apache 的限制。
因此,逐出超时仅适用于文档所说的 'daemon process' 直接发送正常重启信号的情况。也就是说,作为一个整体优雅地重新启动 Apache 不会做任何事情,但会向守护进程本身的 pid 发送优雅的重启信号。
因此,如果此行为很重要,唯一的解决方案是确保您使用 display-name
选项到 WSGIDaemonProcess
指令,以便守护进程与 Apache 进程相比具有唯一的命名,然后仅直接向它们发送信号.
通常这只会成为一个问题,因为一些 Linux 系统完全忽略了 Apache 具有非常好的日志文件轮换系统这一事实,而是通过每天重命名日志文件一次然后尝试进行外部日志文件轮换优雅的重启。人们会看到他们不期望的中断请求的问题。在这种情况下,如果它很重要,您应该使用 Apache 自己的日志文件轮换机制,而不是依赖于外部日志文件轮换系统。