【问题标题】:Share Python Interpreter in Apache Prefork / WSGI分享 Apache Prefork / WSGI 中的 Python 解释器
【发布时间】:2010-11-23 06:26:03
【问题描述】:

我正在尝试使用 WSGI 在 Apache(prefork)中运行 Python 应用程序,以便使用单个 Python 解释器。这是必要的,因为应用程序使用线程同步来防止出现竞争条件。由于 Apache prefork 产生了多个进程,因此代码最终不会在解释器之间共享,因此线程同步是无关紧要的(即每个线程只看到自己的锁,而与其他进程无关)。

设置如下:

  • Apache 2.0(prefork)
  • WSGI
  • Python 2.5

这里是相关的 Apache 配置:

WSGIApplicationGroup %{GLOBAL}
<VirtualHost _default_:80>

WSGIScriptAlias / /var/convergedsecurity/apache/osvm.wsgi

Alias /admin_media/ /var/www/html/admin_media/

<Directory /var/www/html/admin_media>
Order deny,allow
Allow from all
</Directory>

Alias /media/ /var/www/html/media/

<Directory /var/www/html/media>
Order deny,allow
Allow from all
</Directory>

</VirtualHost>

这是我迄今为止尝试过的(都没有奏效):

  1. 添加WSGIApplicationGroup %{GLOBAL}
  2. 在虚拟主机中指定 WSGIDaemonProcessWSGIProcessGroup

    WSGIDaemonProcess osvm 线程=50
    WSGIProcessGroup osvm

有没有办法强制 Apache prefork 使用带有 WSGI 的单个 Python 解释器?文档似乎暗示您可以使用 WSGIDaemonProcess 和 WSGIApplicationGroup 选项,但 Apache 仍然为每个进程创建单独的 Python 解释器。

【问题讨论】:

    标签: apache apache2 mod-wsgi wsgi django-wsgi


    【解决方案1】:

    您不能让 WSGI 应用程序在 UNIX 系统上以嵌入式模式运行,无论是 prefork 还是 worker MPM,因为确实会有多个进程。见:

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

    创建一个由单个进程组成的守护进程组并将 WSGI 应用程序委托给它应该可以实现您想要的。如果它只是您正在谈论的一个已安装的 WSGI 应用程序,您甚至不需要使用 WSGIApplicationGroup。如果你想绝对确定,你也可以设置它。

    VirtualHost 中的配置如下:

    WSGIDaemonProcess osvm
    WSGIProcessGroup osvm
    WSGIApplicationGroup %{GLOBAL}
    
    WSGIScriptAlias / /var/convergedsecurity/apache/osvm.wsgi
    

    虽然 WSGIDaemonProcess 的 'processes=1' 明确表明创建了一个进程,但不要提供该选项,而是让它默认为一个进程。任何使用 'processes' 选项,即使对于一个进程将看到 'wsgi.multiprocess' 设置为 True。

    建议您使用以下简单的测试程序进行测试,而不是使用您实际的 WSGI 应用程序。

    import cStringIO
    import os
    
    def application(environ, start_response):
        headers = []
        headers.append(('Content-Type', 'text/plain'))
        write = start_response('200 OK', headers)
    
        input = environ['wsgi.input']
        output = cStringIO.StringIO()
    
        print >> output, "PID: %s" % os.getpid()
        print >> output
    
        keys = environ.keys()
        keys.sort()
        for key in keys:
            print >> output, '%s: %s' % (key, repr(environ[key]))
        print >> output
    
        output.write(input.read(int(environ.get('CONTENT_LENGTH', '0'))))
    
        return [output.getvalue()]
    

    在输出中,PID 值应该始终相同。 wsgi.multiprocess 标志应该是 False。 mod_wsgi.process_group 值应该是您所称的守护进程组。而 mod_wsgi.application_group 应该是一个空字符串。

    如果这不是您所看到的,请确保您在进行配置更改后实际重新启动了 Apache。同时补充:

    LogLevel debug
    

    到 VirtualHost 的 Apache 配置。这样做会导致 mod_wsgi 在 Apache 错误日志中记录更多关于进程创建和脚本加载的消息,包括正在发生的进程组和应用程序组的详细信息。

    有关调试的其他信息,请参阅:

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

    如果还是有问题,建议你去 Google Groups 上的 mod_wsgi 邮件列表。

    【讨论】:

    • 谢谢,您的回复非常完美。设置守护进程组后,我遇到了几个问题;两者都通过您在 Google 群组中提供的信息解决。具体来说,我必须在 Apache 配置 (code.google.com/p/modwsgi/issues/detail?id=40) 中更早地放置用户和组指令并设置 WSGISocketPrefix。感谢您的帮助。
    猜你喜欢
    • 2011-03-12
    • 2014-09-28
    • 1970-01-01
    • 2021-08-06
    • 2017-02-22
    • 2012-01-11
    • 2012-12-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多