我有一个 Ubuntu 10.04 盒子,使用 mod_wsgi (嵌入模式) 运行几十个 Python Django 站点;更快模式,如果配置正确)。性能波动很大。有时很快,有时延迟几秒钟。smokeping 图表随处可见。
最近,我还为静态内容添加了一个 nginx 代理,希望它能解决性能波动大的问题。但是,尽管它大大减少了 Apache 需要处理的请求数量,但对主要问题却没有帮助。
在运行 htop 时点击网站时,可以看到有时请求几乎是即时的,而有时它会导致 Apache 消耗 100% CPU 几秒钟。我真的不明白这种波动是从哪里来的。
我已经为 Apache 配置了 mpm_worker,如下所示:
StartServers 1
MinSpareThreads 50
MaxSpareThreads 50
ThreadLimit 64
ThreadsPerChild 50
MaxClients 50
ServerLimit 1
MaxRequestsPerChild 0
MaxMemFree 2048
1 个服务器,有 50 个线程,最多 50 个客户端。Munin 和apache2ctl -t
两者都显示出工作者的持续存在;它们不会一直被销毁和创建。然而,它的行为就是这样的。
这告诉我,一旦创建了子解释器,它就应该保留在内存中,但似乎网站必须始终重新加载。
我还有一个 nginx+gunicorn 盒子,性能相当不错。我真的很想知道为什么 Apache 如此随机。
这是一个虚拟主机配置:
<VirtualHost *:81>
ServerAdmin [email protected]
ServerName example.com
DocumentRoot /srv/http/site/bla
Alias /static/ /srv/http/site/static
Alias /media/ /srv/http/site/media
WSGIScriptAlias / /srv/http/site/passenger_wsgi.py
<Directory />
AllowOverride None
</Directory>
<Directory /srv/http/site>
Options -Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
- Ubuntu 10.04
- Apache 2.2.14
- mod_wsgi 的源代码
- nginx 0.7.65
编辑:我在网站的 settings.py 文件中放入了一些代码,每当加载时都会将日期写入 tmp 文件。我现在可以看到该网站并非一直随机重新加载,因此 Apache 必须将其保存在内存中。所以,这很好,只是它并没有让我更接近答案……
编辑:我刚刚发现一个可能与此相关的错误:
File "/usr/lib/python2.6/subprocess.py", line 633, in __init__
errread, errwrite)
File "/usr/lib/python2.6/subprocess.py", line 1049, in _execute_child
self.pid = os.fork()
OSError: [Errno 12] Cannot allocate memory
服务器有 2000 MB 的可用空间,其中 600 MB 应该足够了。Apache 或 WSGI 是否设置了限制?
答案1
您是否尝试过使用 New Relic 来尝试确定它是否是您的 Web 应用程序中的问题?有免费套餐和初始完整试用版。它能为您提供以下方面的概述:
如果所使用的 Web 应用程序或后端服务的特定问题并不突出,WSGI 服务器容量分析报告可能会显示一些信息,它会告诉您是否容量不足。它还可以告诉您是否配置过多并浪费资源,而这种情况实际上经常发生。
顺便说一句,一般来说,我不建议在一个进程中使用 50 个请求线程。最好使用大约 5 个线程和多个进程。但究竟什么是最佳方案确实取决于具体应用程序,它是否正在执行大量 CPU 密集型工作,以及它需要处理多少长时间运行的请求。是否通过同一个 Apache 提供大量静态文件也会影响它,mod_wsgi 的守护进程模式甚至可能是一个更好的整体解决方案。
您使用的 mod_wsgi 版本也非常旧,不过,您不认为这会导致问题。
最后,为了避免一些 Python 的第三方 C 扩展模块出现问题,如果这是该服务器上唯一的 WSGI 应用程序,请设置:
WSGIApplicationGroup %{GLOBAL}
答案2
我修复了这个问题。我将所有生产站点转换为使用自己的进程(所有开发站点也都使用同一个进程),采用守护进程模式。Smokeping 图表现在好多了。性能稳定。
这仍然让我不明白为什么嵌入式模式会出现这些问题,因为据我所知我没有创建/销毁进程,但至少我有一个运行更好的服务器。
编辑:
以 Apache 站点配置为例:
WSGIDaemonProcess mysite12 processes=1 threads=10 display-name=%{GROUP}
WSGIProcessGroup mysite12
然后,对于低优先级的网站,我将其放入wsgi.conf
:
WSGIDaemonProcess developmentsites processes=1 threads=15 display-name=%{GROUP}
然后在 apache conf 中:
WSGIProcessGroup developmentsites
看看区别(也是因为 nginx 代理):