一台虚拟主机上的多个 mod_wsgi 应用程序指向错误的应用程序
Posted
技术标签:
【中文标题】一台虚拟主机上的多个 mod_wsgi 应用程序指向错误的应用程序【英文标题】:Multiple mod_wsgi apps on one virtual host directing to wrong app 【发布时间】:2011-09-29 06:06:42 【问题描述】:我正在尝试在同一域下的子目录中设置两个(或更多)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 会将我发送到工作进程首先加载的任何站点。示例:
-
重新启动配置为服务 6 个线程的 apache
加载example.com/site1/,获取正确的页面
加载example.com/site2/,获取正确页面
再重复 2 和 3 2 次。
反复刷新 example.com/site1/,观察它从一个站点到另一个站点的循环。
实际上,对于任何给定数量的工作进程,无论 WSGIScriptAlias 指令如何,它都会循环遍历将请求发送到它首先遇到的任何一个的工作进程的总数。无论我做什么(设置 WSGIProcessGroup、守护程序模式与嵌入式模式或指令),它都会继续表现出这种行为。
如果有人能指出我在这里做错了什么,那就太棒了!
【问题讨论】:
当您将 WSGI 脚本文件替换为 'code.google.com/p/modwsgi/wiki/…' 中描述的文件时会得到什么? 【参考方案1】:我在单个 Apache 安装上运行了多个 WSGI 应用程序,发现最简单的方法就是拥有多个进程组——每个应用程序一个。
与实际尝试让单个进程同时运行两个(或更多)应用程序相比,一个缺点是,这可能会使用比其他方式更多的常驻内存。但它使它们很好地分开并避免了麻烦。这对你来说可能不是问题(不是我)。
(也可能没那么糟糕,他们可能能够共享很多文本页面?这只是空想;我还没有以任何方式验证这一点,因为我的设置根本没有内存不足)
这是我的 httpd.conf 的一些 sn-ps,大约:
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>
【讨论】:
不鼓励对生产站点使用最大请求数,除非您确实存在无法立即修复的严重内存泄漏。 太棒了!在 Location 块中定义的单独的进程组起作用了。我唯一的遗憾是我没有早点在这里问;-) 遗憾的是它对我不起作用,可能是因为我的WSGIScriptAlias
es 是/
和/foo
。有什么办法吗?
"Don't Do that Then" :-) ...听起来你希望 Apache 在任何时候都使用 /foo 处理程序...“匹配”某些东西,但在其他情况下使用 / 处理程序案例。这不是它的工作原理。没有动态返回 Apache 并说“没关系,我毕竟无法处理此请求,让其他人尝试”的机制。 / 处理程序将获取所有内容,而 /foo 将永远没有机会。也许您可以拥有 /foo 和 /bar 并在 / 到 /bar 或一些类似的解决方案中进行一些重定向。 (请注意,通过这样做,您的重定向集将作为边界的明确定义)
@MarkWinterbottom 我知道我参加聚会迟到了,但遇到了同样的问题。看看这是否有帮助:***.com/a/23568825/211153【参考方案2】:
Domingo Ignacio 的回答让我走上了正轨。我想指出一个关于使它工作的重要事实:两个进程组必须在相同虚拟主机内。 (这是基于我对 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>
去掉中间和标签,得到一个VirtualHost,解决了问题:
<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>
【讨论】:
如果我们有两个配置文件,其中一个虚拟主机。他们可以工作吗?【参考方案3】:我自己也遇到过这个问题。我没有尝试正确配置 Apache,而是决定使用单个 WSGIScriptAlias 并使用 WSGI 中间件将请求路由到正确的应用程序。我的代码在https://github.com/zhemao/flotilla。我没有对它进行太多测试,因此请谨慎使用,但我希望它会有所帮助。
【讨论】:
由于 Django 依赖于单个 DJANGO_SETTINGS_MODULE 环境变量,因此您不能对两个不同的 Django 站点执行此操作,该值不能从一个请求更改为下一个请求。【参考方案4】:有谁知道如何让它在根目录下与其中一个应用程序一起工作?
这是我目前正在尝试的。根目录上的 app2 服务查找,但我收到 400 错误请求:“浏览器(或代理)在 app1 上发送了此服务器无法理解的请求”。
<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>
【讨论】:
您需要为您的别名专门设置进程组(请参阅docs)。设置WSGIScriptAlias /app1 /app1/app1.wsgi process-group=app1
和WSGIScriptAlias / /app2/app2.wsgi process-group=app2
,就可以了。以上是关于一台虚拟主机上的多个 mod_wsgi 应用程序指向错误的应用程序的主要内容,如果未能解决你的问题,请参考以下文章
apache/mod_wsgi - 如何使用不同的 python 虚拟环境配置多个 webapps
用于多个客户端的 Django + Celery + Apache mod_wsgi + Postgres + RabbitMQ 应用程序
使用 mod_wsgi 在 Apache 上部署多个 django 应用程序