使用 nginx 代理的 Apache+mod_wsgi 上的 Python Django 站点:性能波动很大

使用 nginx 代理的 Apache+mod_wsgi 上的 Python Django 站点:性能波动很大

我有一个 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 代理):

在此处输入图片描述

相关内容