同时运行两个Django项目,mod_wsgi表现异常

11
我正在尝试同时运行两个Django项目。我恰好使用了mod_wsgi,并发现网站表现异常。或许有一些变通的方法,但我想知道我错过了什么以及如何解决这个问题。
在Apache配置中:
# Setup the Python environment
# As root owns basically everything on a Amazon AMI and root
# cannot be used. Create a folder under /var/run/wsgi
# with the owner as ec2-user and group ec2-user.
WSGISocketPrefix /var/run/wsgi
# Call your daemon process a name
WSGIDaemonProcess pydaemon processes=1 threads=5
# Call your daemon process group a name
WSGIProcessGroup pydaemon
# Point to where the handler file is. This will be different
# If you are using some other framework.
WSGIScriptAlias /test /var/www/html/test/wsgi.py
WSGIScriptAlias /proto /var/www/html/proto/wsgi.py

重新启动Apache后,如果我连接到“/proto”,则会显示proto网站。然而,如果我在不重新启动Apache的情况下连接到“/test”,则仍然会显示proto网站,并且无法访问test网站。

现在我重新启动了Apache,这次我先进入“/test”。测试网站出现了!但是,如果我去“/proto”,它仍然显示测试站点,而不是proto站点。

这是什么原因?我已经为每个应用程序分别添加了SESSION_COOKIE_PATH,但问题仍然存在。


[更新]

我还尝试过以下操作,给不同的WSGI应用程序组命名,但没有成功。

Alias /cuedit /var/local/test/wsgi.py
<Location /test>
SetHandler wsgi-script
Options +ExecCGI
WSGIApplicationGroup test
</Location>
Alias /proto /var/local/proto/wsgi.py
<Location /proto>
SetHandler wsgi-script
Options +ExecCGI
WSGIApplicationGroup proto
</Location>

[更新]

我从守护进程模式改成了嵌入式模式。我猜问题是两个实例共享了同一个mod_wsgi守护进程,导致它们的命名空间发生冲突。

我本来以为它们应该被正确处理,但在守护进程模式下,我没能搞定。


请不要将您的代码放在/var/www/html下。 - Daniel Roseman
在每种情况下,我在Apache错误日志中没有发现任何错误,而访问日志显示每个目录上的HTTP GET请求是正确的。 - MHC
@DanielRoseman 你的意思是将HTML目录放在外面吗? - MHC
1
是的,这是代码,而不是HTML。您不希望它被作为原样提供。请将其放在Web根目录之外。 - Daniel Roseman
4个回答

14

可以将这个作为解决办法:

WSGIDaemonProcess pydaemon-1 processes=1 threads=5
WSGIDaemonProcess pydaemon-2 processes=1 threads=5

WSGIScriptAlias /test /var/www/html/test/wsgi.py

<Location /test>
WSGIProcessGroup pydaemon-1
WSGIApplicationGroup %{GLOBAL}
</Location>

WSGIScriptAlias /proto /var/www/html/proto/wsgi.py

<Location /proto>
WSGIProcessGroup pydaemon-2
WSGIApplicationGroup %{GLOBAL}
</Location>
这将强制每个应用程序进入单独的守护进程组,并且它们不应该相互干扰。如果仍然无法正常工作,则可能是由于WSGI脚本文件存在问题。

我正是希望能够做到这一点。非常感谢你! - MHC
这是一个解决方法。除非以某种方式覆盖了WSGIApplicationGroup以强制使用单个解释器,否则您所拥有的应该可以正常工作。 - Graham Dumpleton

4

我也有两个 Django 项目,但每个项目都在不同的端口上运行(httpd 配置),看起来像这样:

<VirtualHost *:80>
    ServerAdmin xx
    ServerName xx
    ServerAlias xx
    ErrorLog /path/to/first/project/logs/error.log
    CustomLog /path/to/first/project/logs/access.log combined

    Alias /static/ /path/to/first/project/sitestatic

    WSGIDaemonProcess app processes=1 threads=15 display-name=%{GROUP}
    WSGIProcessGroup app

    WSGIScriptAlias / /path/to/first/project/django.wsgi

    <Directory /path/to/first/project/apache>
       Order deny,allow
       Allow from all
     </Directory>
</VirtualHost>

<VirtualHost *:8080>
    ServerAdmin xx
    ServerName xx
    ServerAlias xx
    ErrorLog /path/to/second/project/logs/error.log
    CustomLog /path/to/second/project/logs/access.log combined

    WSGIDaemonProcess app1 processes=1 threads=15 display-name=%{GROUP}
    WSGIProcessGroup app1

    WSGIScriptAlias / /path/to/second/project/apache/django.wsgi

     <Directory /path/to/second/project/apache>
         Order deny,allow
         Allow from all
     </Directory>
</VirtualHost>

谢谢您的回答。如果我不使用虚拟主机,有什么想法为什么会出现这个问题? - MHC
这是一个被低估的答案。它完美地满足了我的需求。 - steve-gregory

1

问题可能与Apache在WSGI应用程序之间共享Python子解释器有关。尝试将以下内容添加到Apache配置中以避免共享:

WSGIApplicationGroup %{GLOBAL}

请查看这篇博客文章,了解深入的解释和额外的技巧(也要检查评论)。


1
你肯定不想要这样做。这将强制它们在同一个地方运行,而不是分开运行。默认应该是“WSGIApplicationGroup %{RESOURCE}”,这样可以保持它们的独立性。该博文建议这样做来解决一种不同类型的问题。 - Graham Dumpleton
我猜 @Lycha 的解决方案也可能与此有关,因为尽管 %{GLOBAL} 强制它们在同一个解释器中运行,但它禁止使用子解释器,如果问题出现在子解释器中,那么这个方法可能会解决问题。不幸的是,%{GLOBAL} 没有解决问题。 - MHC
@GrahamDumpleton,无论是%{GLOBAL}还是%{RESOURCE}(默认值),都没有解决问题,但感谢你们的评论!你们帮助我更多地了解了mod_wsgi。 - MHC
1
顺便说一句,我从未想过会收到 Graham Dumpleton 的评论! - MHC
我本想详细回答,但因为要去海外参加PyCon有些忙。像这样解决技术问题在SO上很难。我会给出一个解决方法作为答案。 - Graham Dumpleton

0

无法对Graham给出的答案进行评论,因此我添加了自己的答案。

对我来说,问题确实是Python解释器,但我还必须为每个解释器添加python-path。以下是一个示例配置:

WSGIDaemonProcess py_app1 processes=1 threads=5 python-path=/path/to/app1
WSGIScriptAlias /app1 /path/to/app1/wsgi.py
<Directory /path/to/app1>
    <Files wsgi.py>
        Order deny,allow
        Allow from all
    </Files>
</Directory>
<Location /app1>
    WSGIProcessGroup py_app1
    WSGIApplicationGroup %{GLOBAL}
</Location>

WSGIDaemonProcess py_app2 processes=1 threads=5 python-path=/path/to/app2
WSGIScriptAlias /app2 /path/to/app2/wsgi.py
<Directory /path/to/app2>
    <Files wsgi.py>
        Order deny,allow
        Allow from all
    </Files>
</Directory>
<Location /app2>
    WSGIProcessGroup py_app2
    WSGIApplicationGroup %{GLOBAL}
</Location>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接