mod_wsgi 强制重新加载模块

15
有没有一种方法可以让mod_wsgi在每次加载时重新加载所有模块(也许是特定目录中的模块)?
在编写代码时,每次更改都需要重启apache非常麻烦。到目前为止,我找到的唯一选项是在每个导入下面放置 modname = reload(modname),但那也很烦人,因为这意味着我将不得不在以后的某个时候去掉它们。
4个回答

14

链接:

http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode

需要强调的是,在UNIX系统上,必须使用mod_wsgi的守护进程模式,并实现文档中描述的代码监视器。整个进程重新加载选项不适用于mod_wsgi的嵌入式模式。尽管在Windows系统上,唯一的选项是嵌入式模式,但可以通过在代码监视脚本中触发Apache的内部重启来完成相同的操作。文档中也有描述。


12
以下解决方案仅适用于Linux用户,并已在Ubuntu Server 12.04.1下进行测试。
要在守护进程模式下运行WSGI,您需要在Apache配置文件中指定WSGIProcessGroupWSGIDaemonProcess指令,例如:
WSGIProcessGroup my_wsgi_process
WSGIDaemonProcess my_wsgi_process threads=15

更多细节可在http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives中获得。

使用守护进程的另一个好处是,在同一服务器上运行多个WSGI站点时,尤其是使用VirtualHost指令时,可以提高稳定性。如果不使用守护进程,我发现两个Django网站会相互冲突,轮流出现500 Internal Server Error错误。

此时,您的服务器实际上已经监视您的WSGI站点进行更改,虽然它只监视使用WSGIScriptAlias指定的文件,例如:

WSGIScriptAlias / /var/www/my_django_site/my_django_site/wsgi.py

这意味着您可以通过更改WSGI脚本来强制重载WSGI守护进程。当然,您不必更改其内容,而是...
$ touch /var/www/my_django_site/my_django_site/wsgi.py

通过使用上述方法,您可以在生产环境中自动重新加载WSGI网站,而无需重新启动/重新加载整个Apache服务器,或修改您的WSGI脚本以进行不安全的生产代码更改监视。
当您拥有自动部署脚本并且不想在部署时重启Apache服务器时,这尤其有用。
在开发过程中,您可以使用文件系统更改监视器来调用 touch wsgi.py ,每次站点下的模块发生更改时,例如pywatch

5

如果你需要关于代码重载的答案,可以参考mod_wsgi的文档


Ian,这是因为你使用的是Windows或者在嵌入式模式下使用mod_wsgi吗?否则那个页面有一些自动重启的代码,它可以完美地工作。 - Van Gale
不,这是在Linux上。 自动重新加载仅适用于正在访问的脚本,而不适用于脚本调用的模块。 - Ian
2
如果这个答案没有帮助,为什么它是正确的答案? - Yarin

3
我知道这是一个旧的线程,但这可能会对某些人有所帮助。要在特定目录中的任何文件被写入时终止进程,您可以使用类似以下内容的代码:

monitor.py

import os, sys, time, signal, threading, atexit
import inotify.adapters

def _monitor(path):

    i = inotify.adapters.InotifyTree(path)

    print "monitoring", path
    while 1:
        for event in i.event_gen():
            if event is not None:
                (header, type_names, watch_path, filename) = event
                if 'IN_CLOSE_WRITE' in type_names:
                    prefix = 'monitor (pid=%d):' % os.getpid()
                    print "%s %s/%s changed," % (prefix, path, filename), 'restarting!'
                    os.kill(os.getpid(), signal.SIGKILL)

def start(path):

    t = threading.Thread(target = _monitor, args = (path,))
    t.setDaemon(True)
    t.start()

    print 'Started change monitor. (pid=%d)' % os.getpid()

在服务器启动时,请像这样调用它:

server.py

import monitor

monitor.start(<directory which contains your wsgi files>)

如果您的主服务器文件在包含所有文件的目录中,您可以按照以下方式进行:

monitor.start(os.path.dirname(__file__))

添加其他文件夹留给您自己完成...

您需要 'pip install inotify'

这段代码是从这里抄袭的: https://code.google.com/archive/p/modwsgi/wikis/ReloadingSourceCode.wiki#Restarting_Daemon_Processes

这是对我的重复问题的答案: WSGI process reload modules


是的,那是真的。 - Charlie Skilbeck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接