在Apache Prefork/WSGI中共享Python解释器

在Apache Prefork/WSGI中共享Python解释器,apache,apache2,mod-wsgi,wsgi,django-wsgi,Apache,Apache2,Mod Wsgi,Wsgi,Django Wsgi,我正在尝试在Apache(prefork)中使用WSGI运行Python应用程序,以便使用单个Python解释器。这是必要的,因为应用程序使用线程同步来防止争用情况发生。由于Apache prefork生成多个进程,代码最终不会在解释器之间共享,因此线程同步是不相关的(即每个线程只看到自己的锁,而锁与其他进程无关) 以下是设置: Apache2.0(预工作) WSGI Python 2.5 以下是相关的Apache配置: WSGIApplicationGroup %{GLOBAL} <

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

以下是设置:

  • Apache2.0(预工作)
  • 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>
WSGIApplicationGroup%{GLOBAL}
WSGIScriptAlias//var/convergedsecurity/apache/osvm.wsgi
别名/admin\u media//var/www/html/admin\u media/
命令拒绝,允许
通融
别名/media//var/www/html/media/
命令拒绝,允许
通融
以下是我迄今为止所做的尝试(没有一个成功):

  • 添加
  • 在虚拟主机内指定WSGIDaemonProcessWSGIProcessGroup

    WSGIDaemonProcess osvm线程=50
    WSGIProcessGroup osvm


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

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

    创建一个由单个进程组成的守护进程组,并将WSGI应用程序委托给该进程组应该可以实现您想要的。如果您所说的WSGIApplicationGroup只是一个挂载的WSGI应用程序,那么您甚至不需要使用它。如果你想绝对确定,你也可以设置它

    因此,VirtualHost中的配置将是:

    WSGIDaemonProcess osvm
    WSGIProcessGroup osvm
    WSGIApplicationGroup %{GLOBAL}
    
    WSGIScriptAlias / /var/convergedsecurity/apache/osvm.wsgi
    
    尽管WSGIDaemonProcess的“processs=1”明确表示创建了一个进程,但不要提供该选项,只允许它默认为一个进程。任何使用“进程”选项的情况下,即使对于一个进程,也会看到“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_组值应该是您所称的守护进程组。mod_wsgi.application_组应该是一个空字符串

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

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

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


    如果仍然存在问题,建议您访问Google Groups上的mod_wsgi邮件列表。

    谢谢,您的回复非常完美。在我设置了守护进程组之后,我遇到了一些问题;这两个问题都是通过您提供的有关谷歌集团的信息解决的。具体地说,我必须在前面的Apache config()中放置User和Group指令,并设置WSGISocketPrefix。谢谢你的帮助。