mod_wsgi错误 - 类.__ dict__在限制模式下无法访问

时间:2012-05-11 20:07:03

标签: python apache mod-wsgi wsgi pyramid

这开始在我们的生产服务器上咬我们的屁股真的很难。我们偶尔会看到这个(每周1次请求)。当时我们发现这是因为mod_wsgi在一些配置中做了一些时髦的东西。由于我们无法追踪错误的原因,我们认为它不需要立即关注。

然而今天,在我们的一台生产服务器上,这确实发生了所有服务器请求的10%;这是所有服务器请求的10%失败,并出现同样的错误:

mod_wsgi (pid=1718): Target WSGI script '/installation/dir/our-program/prod-dispatch.wsgi' cannot be loaded as Python module.
mod_wsgi (pid=1718): Exception occurred processing WSGI script '/installation/dir/our-program/prod-dispatch.wsgi'.
Traceback (most recent call last):
  File "/installation/dir/our-program/prod-dispatch.wsgi", line 7, in <module>
    from pyramid.paster import get_app
  File "/installation/dir/venv/local/lib/python2.7/site-packages/pyramid-1.3a6-py2.7.egg/pyramid/paster.py", line 12, in <module>
    from pyramid.scripting import prepare
  File "/installation/dir/venv/local/lib/python2.7/site-packages/pyramid-1.3a6-py2.7.egg/pyramid/scripting.py", line 1, in <module>
    from pyramid.config import global_registries
  File "/installation/dir/venv/local/lib/python2.7/site-packages/pyramid-1.3a6-py2.7.egg/pyramid/config/__init__.py", line 61, in <module>
    from pyramid.config.assets import AssetsConfiguratorMixin
  File "/installation/dir/venv/local/lib/python2.7/site-packages/pyramid-1.3a6-py2.7.egg/pyramid/config/assets.py", line 83, in <module>
    @implementer(IPackageOverrides)
  File "/installation/dir/venv/local/lib/python2.7/site-packages/zope.interface-3.8.0-py2.7-linux-x86_64.egg/zope/interface/declarations.py", line 480, in __
    classImplements(ob, *self.interfaces)
  File "/installation/dir/venv/local/lib/python2.7/site-packages/zope.interface-3.8.0-py2.7-linux-x86_64.egg/zope/interface/declarations.py", line 445, in cl
    spec = implementedBy(cls)
  File "/installation/dir/venv/local/lib/python2.7/site-packages/zope.interface-3.8.0-py2.7-linux-x86_64.egg/zope/interface/declarations.py", line 285, in im
    spec = cls.__dict__.get('__implemented__')
RuntimeError: class.__dict__ not accessible in restricted mode

Ubuntu Precise,64位,使用最新的Apache,mod_wsgi,Python 2.7,在守护程序模式下使用mpm_worker + mod_wsgi。这是服务器上运行的唯一程序,配置中只有一个wsgi解释器。这是因为mpm_worker产生新线程还是什么?更重要的是 - 我们如何解决它。

我们有以下内容将请求细分为基于cookie的4个守护进程。

WSGIPythonOptimize 1

WSGIDaemonProcess sticky01 processes=1 threads=16 display-name=%{GROUP}
WSGIDaemonProcess sticky02 processes=1 threads=16 display-name=%{GROUP}
WSGIDaemonProcess sticky03 processes=1 threads=16 display-name=%{GROUP}
WSGIDaemonProcess sticky04 processes=1 threads=16 display-name=%{GROUP}

<VirtualHost *:81>
    ...
    WSGIRestrictProcess sticky01 sticky02 sticky03 sticky04
    WSGIProcessGroup %{ENV:PROCESS}
    ...

    WSGIScriptAlias / /installation/dir/our-program/prod-dispatch.wsgi        
</VirtualHost>

1 个答案:

答案 0 :(得分:10)

众所周知,多个子解释器在C扩展中不能很好地发挥作用。但是,我没有意识到默认设置是非常不幸的。 ModWSGI wiki明确指出WSGIApplicationGroup指令的默认值是%{RESOURCE},其效果应为

  

应用程序组名称将设置为服务器主机名和端口   至于%{SERVER}变量,WSGI环境的值   变量SCRIPT_NAME以文件分隔符分隔   字符。

这意味着对于访问服务器时遇到的每个Host:头,mod_wsgi会产生一个新的子解释器,然后加载C扩展。

我在这个本地服务器上使用 links 浏览器访问localhost.invalid:81时不知不觉地触发了错误,导致我们的4个WSGIDaemonProcesses中的一个因所有未来的传入请求而失败。

Summa summarum:总是在将mod_wsgi与金字塔或任何其他使用C扩展的框架一起使用时,请确保WSGIApplicationGroup始终设置为%{GLOBAL} 。换句话说,使用默认设置的结果会让你在脚下拍摄自己,之后你可能也想拍摄自己的头部。