一个虚拟主机上有多个mod_wsgi应用程序,但指向错误的应用程序

45

我正在尝试在同一域名下设置两个(或更多)Django应用程序的子目录,例如:

http://example.com/site1/
http://example.com/site2/

我知道通常可以通过设置Apache虚拟主机来实现这一点:

<VirtualHost *:80>
    ...
    WSGIScriptAlias /site1 /path/to/site1.wsgi
    WSGIScriptAlias /site2 /path/to/site2.wsgi
</VirtualHost>

现在,我已经验证了每个站点单独运行的情况。但是当我尝试同时运行两个站点时,Apache会将我发送到工作进程先加载的任何一个站点。例如:

  1. 重新启动配置为提供6个线程的Apache
  2. 加载example.com/site1/,获取正确的页面
  3. 加载example.com/site2/,获取正确的页面
  4. 重复2和3两次。
  5. 反复刷新example.com/site1/,观察它从一个站点循环到另一个站点。

实际上,对于任何给定数量的工作进程,它都会循环通过所有工作进程数量,将请求发送到第一个遇到的工作进程,而不管WSGIScriptAlias指令如何。无论我做什么 (设置WSGIProcessGroup、守护进程模式与嵌入模式,或指令),它仍然表现出这种行为。

如果有人能指出我在这里做错了什么,那就太棒了!


4个回答

58

我曾经在单个Apache安装中运行多个WSGI应用程序,发现最简单的方法是为每个应用程序设置一个进程组。

与尝试让单个进程运行两个或更多应用程序相比,一个缺点是这可能会使用比您可以通过其他方式得到的更多的常驻内存。但它可以很好地将它们分开并避免麻烦。对于您来说可能不是一个问题(对我来说也不是)。

这可能也不那么糟糕,它们可以共享很多文本页面?这只是空想;我没有以任何方式验证过这一点,因为我的设置完全没有受限于内存。

以下是我的httpd.conf的一些片段,大约如下:

WSGIDaemonProcess khdx_wsgi user=galdosd group=galdosd maximum-requests=10000
WSGIScriptAlias /khdx /home/galdosd/khdxweb/rel/khdx/apache/django.wsgi
<Location /khdx>
WSGIProcessGroup khdx_wsgi
</Location>

WSGIDaemonProcess sauron_wsgi user=galdosd group=galdosd maximum-requests=10000
WSGIScriptAlias /sauron /home/galdosd/finalsauronweb/django-root/apache/django.wsgi
<Location /sauron>
WSGIProcessGroup sauron_wsgi
</Location>

3
除非您确实有无法立即修复的严重内存泄漏问题,否则不建议在生产网站上使用maximum-requests。请注意避免过度使用该选项。 - Graham Dumpleton
1
太棒了!在Location块中定义的单独进程组起作用了。我唯一的遗憾是没有早点在这里问;-) - Gabriel Hurley
3
很遗憾,这对我没有起作用,可能是因为我的WSGIScriptAlias//foo。有什么解决办法吗? - Timmmm
2
“不要那样做” :-) …听起来你希望Apache在某些情况下使用/foo处理程序,但在其他情况下使用/handler。这不是它的工作方式。没有动态返回Apache并说“算了,我无法处理这个请求,让其他人尝试”的机制。/ handler将获取所有内容,/foo永远没有机会。也许您可以有/foo和/bar,并在/内进行一些重定向到/bar或类似解决方案。 (请注意,通过这样做,您的重定向集充当边界的显式定义) - Domingo Ignacio
1
@MarkWinterbottom 我知道我来晚了,但我遇到了同样的问题。看看这个能否帮助你:https://dev59.com/oX_aa4cB1Zd3GeqP0j-p#23568825 - rszalski
显示剩余7条评论

15

Domingo Ignacio的答案让我找对了方向。我想要指出一个关键事实,使其正常工作:这两个进程组必须在同一个 VirtualHost 内。(这是基于我在Ubuntu 12.04.3 LTS、Apache 2.2.22和多个用Python编写的WSGI应用程序测试的结果。)

例如,下面的配置无法正常工作,导致可以访问app1但访问app2时会出现404错误:

<VirtualHost *>
        WSGIDaemonProcess app1 user=someuser group=somegroup threads=5
        WSGIScriptAlias /app1 /app1/app1.wsgi

        <Location /app1>
                WSGIProcessGroup app1
        </Location>
</VirtualHost>

<VirtualHost *>
        WSGIDaemonProcess app2 user=someuser group=somegroup threads=5
        WSGIScriptAlias /app2 /app2/app2.wsgi

        <Location /app2>
                WSGIProcessGroup app2
        </Location>
</VirtualHost>
Removing the middle </VirtualHost> and <VirtualHost> tags, so as to have a single VirtualHost, solved the problem:
<VirtualHost *>
        WSGIDaemonProcess app1 user=someuser group=somegroup threads=5
        WSGIScriptAlias /app1 /app1/app1.wsgi

        <Location /app1>
                WSGIProcessGroup app1
        </Location>

        WSGIDaemonProcess app2 user=someuser group=somegroup threads=5
        WSGIScriptAlias /app2 /app2/app2.wsgi

        <Location /app2>
                WSGIProcessGroup app2
        </Location>
</VirtualHost>

如果我们有两个配置文件,每个文件中都有一个虚拟主机,它们能够正常工作吗? - user11269100

1

我自己也遇到了这个问题。我不再尝试正确配置Apache,而是决定使用单独的WSGIScriptAlias,并使用WSGI中间件将请求路由到正确的应用程序。我的代码在 https://github.com/zhemao/flotilla 上。我没有进行过太多测试,因此请谨慎使用,但我希望它能有所帮助。


1
由于Django依赖于单个DJANGO_SETTINGS_MODULE环境变量,该值无法在一个请求到另一个请求之间更改,因此您无法使用两个不同的Django站点来完成此操作。 - Graham Dumpleton

0

有人知道如何将其与根目录下的一个应用程序配合使用吗?

这是我目前正在尝试的。根目录下的app2可以正常运行,但在app1上却出现了400错误请求:“浏览器(或代理)发送了一个服务器无法理解的请求”。

<VirtualHost *>
    WSGIDaemonProcess app1 user=someuser group=somegroup threads=5
    WSGIScriptAlias /app1 /app1/app1.wsgi

    <Location /app1>
            WSGIProcessGroup app1
    </Location>

    WSGIDaemonProcess app2 user=someuser group=somegroup threads=5
    WSGIScriptAlias / /app2/app2.wsgi

    <Location / >
            WSGIProcessGroup app2
    </Location>

你需要为你的别名(参见文档)明确设置进程组。 设置 WSGIScriptAlias /app1 /app1/app1.wsgi process-group=app1WSGIScriptAlias / /app2/app2.wsgi process-group=app2,然后它应该可以工作了。 - lukover

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