我有一个使用Apache的专用服务器来监听通过SSL提供API服务的九个非标准端口(8xxx)。端口80和443用于提供静态内容和“覆盖”服务,用于指示其他服务的状态。
几天后,服务开始失败,因为似乎Apache正在将服务请求定向到覆盖服务而不是预期的服务。重新启动Apache修复此问题,直到它再次发生。
服务使用wsgi实现。
传统的金字塔API服务配置如下:
WSGIApplicationGroup %{GLOBAL}
WSGIPassAuthorization On
WSGIDaemonProcess pyramid user=ubuntu group=ubuntu threads=4 \
python-path=/home/ubuntu/ev_mis/lib/python2.7/site-packages
WSGIScriptAlias /mis /home/ubuntu/ev_mis/mis.wsgi
<Directory /home/ubuntu/ev_mis>
WSGIProcessGroup pyramid
Order allow,deny
Allow from all
</Directory>
其他八个API服务使用Django,配置如下:
# Built automatically on Wed Sep 25 13:59:51 2013
Listen 8325
<VirtualHost _default_:8325>
DocumentRoot /usr/local/services/h/rb/mis/mis_site/mis_site
Alias /media /usr/local/services/h/rb/mis/mis_site/mis_site/media
Alias /static /usr/local/services/h/rb/mis/mis_site/mis_site/assets
<Directory /usr/local/services/h/rb/mis/mis_site/mis_site>
Order allow,deny
Allow from all
</Directory>
SetEnv DJANGO_SETTINGS_MODULE mis_site.settings.h
WSGIScriptAlias / /usr/local/orb_services/h/rb/mis/mis_site/mis_site/mis_site/wsgi.py
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/domain.crt
SSLCertificateKeyFile /etc/apache2/ssl/domain.key
SSLCertificateChainFile /etc/apache2/ssl/chain.crt
SSLOptions +StrictRequire
</VirtualHost>
最后是覆盖服务配置:
<VirtualHost *:80>
DocumentRoot /var/www
Alias /static /var/www/static
<Directory /var/www/>
Order allow,deny
Allow from all
</Directory>
Alias /thumbnails /var/www/thumbnails
<Directory /var/www/thumbnails>
Order allow,deny
Allow from all
</Directory>
WSGIScriptAlias / /var/www/overwatch/overwatch/wsgi.py
ErrorLog ${APACHE_LOG_DIR}/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
这是一个示例wsgi.py文件:
import os
from os.path import abspath, dirname
from sys import path
from os import environ
SITE_ROOT = dirname(dirname(abspath(__file__)))
path.append(SITE_ROOT)
from django.core.wsgi import get_wsgi_application
def application(req_environ, start_response):
environ["DJANGO_SETTINGS_MODULE"] = req_environ.get("DJANGO_SETTINGS_MODULE",
environ.get("DJANGO_SETTINGS_MODULE",
None))
return get_wsgi_application()(req_environ, start_response)
例如:https://example.com/生成覆盖状态表,https://example.com:8123/data/生成其中一个服务的服务数据。
分析显示,apache错误地将调用指向了覆盖服务。例如,https://example.com:8123/data/现在产生未找到的页面,调试跟踪显示它已由overwatch wsgi服务提供。
一旦发生这种情况,它会一直发生,直到我重新启动apache服务。然后一切都很好,直到它再次发生。 Apache没有报告任何配置问题,并且启动/重启很好。
目前服务器只是经历了非常轻的测试流量,但它计划很快上线,我不知道如何解决这个问题...当我重新配置整个事情时,可能会咬紧牙关并推迟发射使用nginx / gunicorn代替apache,感觉就像一个警察。
答案 0 :(得分:1)
一些评论。
更新1
而不是使用:
from django.core.wsgi import get_wsgi_application
def application(req_environ, start_response):
environ["DJANGO_SETTINGS_MODULE"] = req_environ.get(
"DJANGO_SETTINGS_MODULE". environ.get("DJANGO_SETTINGS_MODULE", None))
return get_wsgi_application()(req_environ, start_response)
您应该使用:
from django.core.wsgi import get_wsgi_application
_application = get_wsgi_application()
def application(req_environ, start_response):
environ["DJANGO_SETTINGS_MODULE"] = req_environ.get(
"DJANGO_SETTINGS_MODULE", environ.get("DJANGO_SETTINGS_MODULE", None))
return _application(req_environ, start_response)
你在每个请求上调用get_wsgi_application(),这是一个坏主意。它导致在每个请求上创建WSGI处理程序的新实例,这不是必需的。这样做也会搞砸New Relic等监控工具的操作。