在WSGI中以守护进程模式运行pdb

3 投票
1 回答
1166 浏览
提问于 2025-04-17 00:29

我在Apache 2.2上用mod wsgi运行一个Python脚本。

请问在wsgi的守护进程模式下,能不能在Python脚本中使用pdb.set_trace()?

补充说明 我想用守护进程模式而不是嵌入模式的原因是,守护进程模式可以让我在不每次都重启Apache服务器的情况下重新加载代码(而嵌入模式是需要重启的)。我希望能够在不重启Apache的情况下使用代码重新加载,同时还能使用pdb……

1 个回答

1

我也遇到过类似的需求,想要使用强大的 pdb 调试工具,在我想调试的地方加上 pdb.set_trace(),这样就可以逐步检查 Python 服务器代码了。

没错,Apache 会在一个你无法控制的地方启动 WSGI 应用程序 [1]。但我找到了一种不错的折中办法:

  1. 维护你的 Apache WSGIScriptAlias 设置。

  2. 同时也给自己一个选择,可以在终端中启动 Python 服务器(这样就可以在本地测试,而不是通过 Apache 了)。

所以,如果你像这样使用 WSGIScriptAlias,指向你的 Python WSGI 脚本 webserver.py

<VirtualHost *:443>

    ServerName myawesomeserver
    DocumentRoot /opt/local/apache2/htdocs

    <Directory /opt/local/apache2/htdocs>
        [...]
    </Directory>

    WSGIScriptAlias /myapp /opt/local/apache2/my_wsgi_scripts/webserver.py/

    <Directory /opt/local/apache2/my_wsgi_scripts/>
        [...]
    </Directory>

    [...]
    SSLEngine on
    [...]
</VirtualHost>                                  

那么你的 webserver.py 可以有一个简单的 开关,用来切换是在 Apache 下运行还是手动调试。

在你的配置文件中保持一个标志,比如在某个 settings.py 文件里:

WEBPY_WSGI_IS_ON = True

然后在 webserver.py 中:

import web
import settings

urls = (
    '/', 'excellentWebClass',
    '/store', 'evenClassier',)

if settings.WEBPY_WSGI_IS_ON is True:
    # MODE #1: Non-interactive web.py ; using WSGI
    #   So whenever true, the Web.py application here will talk wsgi.
    application = web.application(urls, globals()).wsgifunc()

class excellentWebClass:
    def GET(self, name):

        # Drop a pdb  wherever you want only if running manually from terminal.
        pdb.set_trace()

        try:
            f = open (name)
            return f.read()
        except IOError:
            print 'Error: No such file %s' % name

if __name__ == "__main__":

    # MODE #2: Interactive web.py , for debugging.
    #   Here you call it directly.  
    app = web.application(urls, globals())
    app.run()

所以当你想要交互式地测试你的 web 服务器时,只需从终端运行它:

$ python webserver.py 8080
starting web...
http://0.0.0.0:8080/

[1] 注释:有一些非常复杂的方法可以让你控制 Apache 的子进程,但我觉得上面的方法要简单得多,如果你只是想调试你的 Python 服务器代码。如果确实有简单的方法,我也很想了解一下。

撰写回答