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

发布于 2024-08-03 15:32:04 字数 1246 浏览 6 评论 0原文

我正在尝试使用 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 解释器。

I am attempting to run a Python application within Apache (prefork) with WSGI in such a way that a single Python interpreter will be used. This is necessary since the application uses thread synchronization to prevent race conditions from occurring. Since Apache prefork spawns multiple processes, the code winds up not being shared between the interpreters and thus the thread synchronization is irrelevant (i.e. each thread only sees it own locks which have no bearing on the other processes).

Here is the setup:

  • Apache 2.0 (prefork)
  • WSGI
  • Python 2.5

Here is the relevant Apache configuration:

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>

Here is what I tried so far (none of which worked):

  1. Adding WSGIApplicationGroup %{GLOBAL}
  2. Specifying WSGIDaemonProcess and WSGIProcessGroup within the virtual host:

    WSGIDaemonProcess osvm threads=50
    WSGIProcessGroup osvm

Is there no way to force Apache prefork to use a single Python interpreter with WSGI? The documents seem to imply you can with the WSGIDaemonProcess and WSGIApplicationGroup options but Apache still creates a separate Python interpreter for each process.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

猫七 2024-08-10 15:32:04

您不能让 WSGI 应用程序在 UNIX 系统上以嵌入式模式运行,无论是 prefork 还是工作 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 网上论坛上的 mod_wsgi 邮件列表。

You can't have the WSGI application run in embedded mode on UNIX systems, whether it be prefork or worker MPM, as there will indeed be multiple processes. See:

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

Creating a daemon process group consisting of single process and delegating WSGI application to that should achieve what you want. You shouldn't even need to use WSGIApplicationGroup if it is only one mounted WSGI application you are talking about. If you want to be absolutely sure though, you can also set it.

Thus configuration within VirtualHost would be:

WSGIDaemonProcess osvm
WSGIProcessGroup osvm
WSGIApplicationGroup %{GLOBAL}

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

Although 'processes=1' for WSGIDaemonProcess makes it explicit that one process is created, don't provide the option though and just let it default to one process. Any use of 'processes' option, even if for one process will see 'wsgi.multiprocess' set to True.

Rather than use your actual WSGI application, I would suggest you test with the following simple test program.

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()]

In the output of that, the PID value should always be the same. The wsgi.multiprocess flag should be False. The mod_wsgi.process_group value should be what ever you called the daemon process group. And the mod_wsgi.application_group should be an empty string.

If this isn't what you are seeing, ensure you actually restarted Apache after making configuration changes. Also add:

LogLevel debug

to Apache configuration for VirtualHost. Doing that will cause mod_wsgi to log a lot more messages in Apache error log about process creation and script loading, including details of process group and application group things are happening for.

For other information on debugging, see:

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

If still problems, suggest you go to the mod_wsgi mailing list on Google Groups.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文