【问题标题】:mod_wsgi force reload modulesmod_wsgi 强制重新加载模块
【发布时间】:2010-10-20 11:27:53
【问题描述】:

有没有办法让 mod_wsgi 在每次加载时重新加载所有模块(可能在特定目录中)?

在处理代码时,每次更改时重新启动 apache 非常烦人。到目前为止,我发现的唯一选择是将 modname = reload(modname) 放在每个导入下方.. 但这也很烦人,因为这意味着我将不得不在以后将它们全部删除..

【问题讨论】:

    标签: python module mod-wsgi reload


    【解决方案1】:

    链接:

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

    应该被强调。还应该强调的是,在 UNIX 系统上必须使用 mod_wsgi 的守护程序模式,并且您必须实现文档中描述的代码监视器。整个进程重新加载选项不适用于 UNIX 系统上 mod_wsgi 的嵌入式模式。尽管在 Windows 系统上唯一的选择是嵌入式模式,但通过从代码监控脚本触发 Apache 的内部重新启动,可以通过一些技巧来做同样的事情。这也在文档中有所描述。

    【讨论】:

      【解决方案2】:

      以下解决方案仅针对 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

      【讨论】:

        【解决方案3】:

        mod_wsgi documentation on code reloading 是您最好的答案。

        【讨论】:

        • Ian,这是因为您在 Windows 上还是在嵌入式模式下使用 mod_wsgi?因为否则该页面有一些用于自动重启的代码并且它可以完美运行。
        • 不,这是在 linux 上。自动重新加载仅适用于正在访问的脚本,而不适用于脚本随后调用的模块。
        • 如果没有帮助,为什么会是这个答案?
        【解决方案4】:

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

        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

        【讨论】:

        • 是的,确实如此
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-16
        • 1970-01-01
        • 2012-06-18
        相关资源
        最近更新 更多