排除Nginx + Gunicorn + Django堆栈上的站点缓慢

时间:2012-05-01 17:19:02

标签: django nginx hosting gunicorn

问题我有

我遇到了一些问题,其中一些网站需要很长时间才能加载(“长时间”我的意思是长达16秒)。有时它们可​​能会完全超时,从而产生Nginx 504错误。通常,当网站超时时,我可以重新加载该网站,它会很快加载。我遇到问题的网站获得的流量非常低。我正在通过加载Django管理员索引页面来测试该站点,以便尝试消除因代码不佳而导致的任何缓慢。还应该注意的是,这个特定的站点只使用Django管理员,因为它只是一个内部网类型的站点,仅供员工使用。

主机设置

我托管的所有网站都在两个Rackspace云服务器上。第一台服务器是我的应用服务器,有1024 MB的RAM,我的第二台服务器是我的数据库服务器,有2048 MB的RAM。应用服务器使用Nginx为每个站点提供服务,Nginx为每个站点的Django Gunicorn工作者提供所有静态文件和代理服务。

在查看数据库服务器RAM和CPU负载时,似乎数据库服务器上的一切正常。

$ free -m
             total       used       free     shared    buffers     cached
Mem:          1999       1597        402          0        200       1007
-/+ buffers/cache:        389       1610
Swap:         4094          0       4094


Top shows a CPU load average of: 0.00, 0.01, 0.05

为了尝试解决正在发生的事情,我写了一个快速的小script,它打印出应用服务器上的内存使用情况。

使用匿名网站域打印的示例:

Celery:     23 MB
Gunicorn:  566 MB
Nginx:       8 MB
Redis:     684 KB
Other:      73 MB

             total       used       free     shared    buffers     cached
Mem:           993        906         87          0         19         62
-/+ buffers/cache:        824        169
Swap:         2047        828       1218

Gunicorn memory usage by webste:
site01.example.com    31 MB
site02.example.com    19 MB
site03.example.com     7 MB
site04.example.com     9 MB
site05.example.com    47 MB
site06.example.com    25 MB
site07.example.com    14 MB
site08.example.com    18 MB
site09.example.com    27 MB
site10.example.com    15 MB
site11.example.com    14 MB
site12.example.com     7 MB
site13.example.com    18 MB
site14.example.com    18 MB
site15.example.com    10 MB
site16.example.com    25 MB
site17.example.com    13 MB
site18.example.com    18 MB
site19.example.com    37 MB
site20.example.com    30 MB
site21.example.com    23 MB
site22.example.com    28 MB
site23.example.com    80 MB
site24.example.com    15 MB
site25.example.com     5 MB

示例Gunicorn配置文件:

pidfile = '/var/run/gunicorn_example.com.pid'
proc_name = 'example.com'
workers = 1
bind = 'unix:/tmp/gunicorn_example.com.sock'

示例Nginx配置:

upstream example_app_server {
    server unix:/tmp/gunicorn_example.com.sock fail_timeout=0;
}

server {

    listen       80;
    server_name  example.com;
    access_log   /var/log/nginx/example.com.access.log;
    error_log    /var/log/nginx/example.com.error.log;

    location = /favicon.ico {
        return  404;
    }

    location  /static/ {
        root  /srv/sites/example/;
    }

    location  /media/ {
        root  /srv/sites/example/;
    }

    location  / {
        proxy_pass            http://example_app_server;
        proxy_redirect        off;
        proxy_set_header      Host             $host;
        proxy_set_header      X-Real-IP        $remote_addr;
        proxy_set_header      X-Forwarded-For  $proxy_add_x_forwarded_for;
        client_max_body_size  10m;
    }

}

正如你所看到的,有很多内存被交换,所以为了解决我的问题,我在应用服务器上升级了ram,这完全修复了网站的缓慢。即使我能够解决这个问题,它花了我比我想要的更长的时间,我仍然觉得我基本上猜测导致网站运行缓慢的原因。这一切都让我想到了我的问题......

问题

  1. 如何判断低流量网站上的网站速度不是由于网站不活动导致网站变为非活动状态,导致Gunicorn必须在网站停用后再次加载网站?是否有防止网站无效的设置?
  2. 好像我有些网站占用了太多内存。我可以使用哪些工具来减少网站使用的内存量?我应该使用一些Python分析工具吗?
  3. 为了确定堆栈中出现瓶颈的程度,需要采取哪些工具和步骤?
  4. 确定您的Gunicorn流程是否被交换或者其他进程是否被交换的最佳方法是什么?
  5. 我托管的大部分网站都没有大量的流量,所以我只使用了一名Gunicorn工作人员。有没有更科学的方法来确定和调整你在一个网站上有多少Gunicorn工人?
  6. 在同一台服务器上托管多个站点时,有没有办法配置使用更少的内存?

3 个答案:

答案 0 :(得分:4)

有很多网站要托管在只有1GB内存的服务器上。你的内存利用率接近100%,你拥有的数字可能是“待机”数字。每个进程的RAM使用情况可以并且将在服务请求的过程中膨胀。马上,您需要为此实例添加更多RAM,更好的是,将一些站点移到另一台服务器上。

关于你的问题:

  1. 你在哪里知道网站变得“无效”,然后,Gunicorn必须再次加载网站?那是垃圾。只要Gunicorn进程正在运行(即没有手动终止或网站上出现错误),它仍然完全初始化并准备就绪,无论是一小时还是一个月。

  2. 你在这里乱砍叶子,根本不受影响。每个Gunicorn进程的内存使用都没有什么特别之处。 需要 RAM才能运行。你的问题是试图在服务不足的服务器上运行太多。没有优化可以在这里拯救你。您需要更多RAM或更多服务器。可能两者都有。

  3. 不需要。同样,问题已经确定。事实上,你发布的数字非常清楚。

  4. 无法可靠地知道哪些进程被交换。它每秒都会改变,取决于哪些是主动运行,需要更多RAM,哪些是不活动的,或者根本不活动。当你的服务器资源紧张时,它花费了一半的时间来确定接下来应该处理哪个进程,特别是如果它们都处于活跃状态并争夺资源。

  5. 是。 Gunicorn推荐2 *核+ 1。所以在双核系统上,那就是5;在四核上,9。然而,在这一个系统上,你无法为每个站点运行5个工作人员。你甚至不能可靠地运行1名工人。

  6. 这取决于“事物”。但是,当多个站点托管在同一台服务器上时,这些服务器的规格是 beasts 。在像你这样的小型VPS实例上,特别是只有1GB的RAM,一个站点几乎是你的极限。两个,也许。

答案 1 :(得分:1)

1)不确定你的意思是什么?在,由nginx禁用?或者工作太慢了?

2和3)django-debug-toolbar和django-debug-logging将是一个很好的起点。如果这没有帮助,那么现在可以转到服务器级别的分析,看看哪些进程导致了问题。

4)使用top:How to find out which processes are swapping in linux?

5)是 - 基准测试。选择一个基准测试工具(例如apachebench)并针对您当前的配置运行测试。调整一些东西。再次运行测试。重复,直到你的性能问题消失!为获得最佳效果,请使用与您的实时流量类似的流量(在URL分配,GET / POST等方面)。

6)是的,在nginx和app级别。通过分析每个站点并提高其内存使用量,您可能会获得最大的收益(参见2)。

答案 2 :(得分:1)

关于:

  

关于你对5的回答,我相信Gunicorn推荐的是   矫枉过正。

我最近对工作人员进行了一些临时测试,并发现,假设你有足够的RAM,2 *核心+ 1经验法则是非常准确的。我发现请求/秒几乎是线性增加,直到我接近这个数字,然后随着操作系统开始捶打而下降。

由于结果很大程度上取决于工作负载,因此请尝试使用不同的值并查看性能达到峰值的位置。