尝试在Apache + mod_wsgi下运行Pyramid,但失败了

3 投票
1 回答
4174 浏览
提问于 2025-04-16 13:29

我在用Apache2服务器,并且安装了mod_wsgi。通过跟着这个教程,我确认了mod_wsgi确实可以正常工作。

问题出现在我尝试运行Pyramid框架的时候。我遇到了内部服务器错误,Apache的错误日志里显示了一个异常:

AssertionError: The EvalException middleware is not usable in a multi-process environment

这是我的虚拟主机设置:

<VirtualHost *:80>
    ServerName  pyramidtest.dev
    DocumentRoot    /srv/pyramidtest.dev/www/
    AssignUserID    pyramidtest nogroup
    WSGIScriptAlias / /srv/pyramidtest.dev/pyramid/load.wsgi
</VirtualHost>

这是我的 load.wsgi 文件:

import site
site.addsitedir('/opt/pyramid/lib/python2.7/site-packages')

from pyramid.paster import get_app

application = get_app('/srv/pyramidtest.dev/pyramid/test/development.ini', 'main')

mod_wsgi是编译成使用 /opt/python2.7 作为Python解释器的,但我是在 /opt/pyramid 下的虚拟环境中运行Pyramid。这就是我在load.wsgi里使用 site.addsitedir() 的原因。

如果需要的话,这里是 apache2 -V 的输出:

Server version: Apache/2.2.9 (Debian)
Server built:   Dec 30 2010 11:50:24
Server's Module Magic Number: 20051115:15
Server loaded:  APR 1.2.12, APR-Util 1.2.12
Compiled using: APR 1.2.12, APR-Util 1.2.12
Architecture:   32-bit
Server MPM:     ITK
  threaded:     no
    forked:     yes (variable process count)
Server compiled with....
 -D APACHE_MPM_DIR="server/mpm/experimental/itk"
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_SYSVSEM_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=128
 -D HTTPD_ROOT=""
 -D SUEXEC_BIN="/usr/lib/apache2/suexec"
 -D DEFAULT_PIDLOG="/var/run/apache2.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_LOCKFILE="/var/run/apache2/accept.lock"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="/etc/apache2/mime.types"
 -D SERVER_CONFIG_FILE="/etc/apache2/apache2.conf"

我缺少了什么呢...?

1 个回答

6

你正在使用EvalException中间件(从你的错误信息可以看出来)。这个错误的解决办法其实在mod_wsgi的调试技巧维基中有提到。

简单来说,由于这个中间件允许你在浏览器中进行交互式调试,所以所有的请求都需要发送到同一个进程;但是你现在是在嵌入模式下运行mod_wsgi,这种模式默认会创建很多进程。

维基中提到:

[...] 如果你想使用这个 基于浏览器的交互式调试器, 在使用mod_wsgi的嵌入模式下 运行你的应用时,你需要 配置Apache,使它只启动一个 子进程来处理请求,并且 不会创建其他进程。为了 实现这一点,你需要的Apache 配置指令如下。

StartServers 1  
ServerLimit 1

切换到守护进程模式(使用单个进程,默认设置)也能解决这个问题,并且推荐使用这种模式,而不是嵌入模式。以下是Apache的指令:

WSGIDaemonProcess pyramidtest.dev display-name=%{GROUP}
WSGIProcessGroup pyramidtest.dev

mod_wsgi还可以为你添加Python路径。如果使用嵌入模式,你可以使用:

WSGIPythonPath /opt/pyramid/lib/python2.7/site-packages

如果使用守护进程模式,则需要在WSGIDaemonProcess指令中使用'python-path'选项。

WSGIDaemonProcess pyramidtest.dev display-name=%{GROUP} python-path=/opt/pyramid/lib/python2.7/site-packages
WSGIProcessGroup pyramidtest.dev

撰写回答