重新加载mod_wsgi守护进程时会有停机时间吗?

5 投票
2 回答
2294 浏览
提问于 2025-04-16 03:55

我在用Apache和mod_wsgi运行一个Django应用。升级的时候会有停机时间吗?

mod_wsgi是以守护进程模式运行的,所以我可以通过修改.wsgi脚本文件来重新加载我的代码,具体方法可以参考“ReloadingSourceCode”文档:http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode。我想,这个重新加载是需要一些时间的。如果在重新加载的时候有请求过来,会发生什么呢?Apache会把这个请求排队,然后等wsgi守护进程准备好后再处理吗?

文档里有这样一句话:

所以,如果你在守护进程模式下使用Django,并且需要修改你的'settings.py'文件,一旦你做了必要的修改,也要修改包含WSGI应用入口点的脚本文件。这样,在下一个请求到来时,进程会被重启,你的Django应用会被重新加载。

在我看来,这意味着Apache会优雅地处理每一个请求,但我还是想确认一下。我的应用不是特别重要(稍微停一下也没关系),所以这个问题主要是学术上的。

谢谢。

2 个回答

1

不会有停机时间。使用旧代码的请求会继续完成,而新的请求会使用新代码。

服务器的负担会稍微增加一点,因为新代码需要加载,但除非你的应用非常庞大,而且服务器已经快要超负荷了,否则你不会察觉到这个变化。

这就像是对整个Apache使用的 apachectl graceful 命令,它可以在不停止服务的情况下启动新的配置。

18

在守护进程模式下,当你修改 WSGI 脚本文件以强制重新加载时,并没有优雅重启的概念。也就是说,不像 Apache 自己那样,它会在等待旧的进程完成当前请求时启动新的 Apache 服务器子进程,对于 mod_wsgi 的守护进程来说,现有的进程必须先退出,才能启动新的进程。

这样做的后果是,mod_wsgi 不能无限期地等待当前请求完成。如果它这样做,就有可能导致所有守护进程都在等待当前请求结束,这样客户端就会明显感到处理请求的延迟。

但另一方面,守护进程也不能立即被杀掉,因为那样会导致当前请求被中断。

因此,存在一个折中的办法。守护进程会等待请求完成后再退出,但如果在关闭的时间段内请求还没有完成,守护进程就会被强制退出,活跃的请求也会被中断。

这个关闭超时时间默认是 5 秒。你可以通过 WSGIDaemonProcess 指令中的 shutdown-timeout 选项来修改这个时间,但在更改之前需要考虑到可能带来的影响。

因此,针对这个具体问题,如果在你修改 WSGI 脚本文件后,仍然有长时间运行的请求在处理,那么就有可能会中断这些活跃的长请求。

接下来你可能会注意到,即使没有长时间运行的请求,进程也会迅速关闭,但仍然需要在新进程中重新加载 WSGI 应用程序。这个过程所花的时间会被视为处理请求的延迟。这个延迟的大小取决于你使用的框架和应用程序。根据我所知道的,启动时间最长的框架是 TurboGears。Django 稍微好一些,而启动时间最短的则是像 Flask 这样的轻量级微框架。

请注意,在这些关闭和启动延迟发生时,任何新到的请求都不会丢失。这是因为 HTTP 监听套接字有一定的深度,连接会在等待被接受时排队。不过,如果到达的请求数量非常庞大,导致队列满了,那么你就会在浏览器中看到连接被拒绝的错误。

撰写回答