如何在Nginx + Gunicorn + Django堆栈上解决网站缓慢问题?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (433)

我遇到的问题

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

主机设置

我所托管的所有网站都位于两台Rackspace云服务器上。第一台服务器是我的应用服务器,它有1024 MB的RAM,而我的第二台服务器是我的数据库服务器,它有2048 MB的RAM。应用服务器使用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

为了尝试排查发生的事情,我编写了一个快速的小脚本,用于打印应用程序服务器上的内存使用情况。

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

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. 当在同一台服务器上托管多个站点时,是否有办法配置事物以使用较少的内存?
提问于
用户回答回答于

1)你的意思是不活跃?在nginx中,由nginx禁用?或者工作速度太慢?

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

4)使用top

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

6)是的,在nginx和应用程序级别。通过分析每个站点并改进其内存使用情况,可能会获得最大收益(请参阅2)。

用户回答回答于

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

至于你的问题:

  1. 你从哪里得到这样的想法,即网站变得“不活跃”,然后,Gunicorn必须再次加载该网站?这是垃圾。只要Gunicorn进程正在运行(即没有手动终止或由于网站上的错误),它仍然完全初始化并准备好,无论是一个小时还是一个月。
  2. 你在这里砍树叶,不改动根。每个Gunicorn进程的内存使用情况都没有什么特别之处。它需要 RAM来运行。你的问题是试图在一台严重动力不足的服务器上运行太多。没有优化会在这里节省你。你需要更多的RAM或更多的服务器。可能都是。
  3. 没必要。同样,问题已经确定。事实上,你发布的数字非常清楚。
  4. 没有办法可靠地知道哪些进程正在交换。它每秒都在变化,并且取决于哪些主动运行,需要更多的RAM以及哪些是不活动的或者根本不活动。当你的服务器资源紧张时,花费一半时间才能确定下一步要处理哪些进程,特别是如果它们都处于活动状态并争夺资源。
  5. 是。Gunicorn建议2 *内核+ 1。所以在双核系统上,这是5; 在一个四核上,9.然而,在这个系统上,你无法为每个这样的站点运行5个员工。你甚至不能为每个人可靠运行1名工人。
  6. 这取决于“事物”。但是,当多个站点托管在同一台服务器上时,这些服务器就是特定的野兽。在一个像一样的小型VPS实例上,尤其是只有1GB内存的情况下,一个站点几乎是限制。也许两个。

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动