20

我遇到的问题

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

主机设置

我托管的所有站点都在两台 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

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

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

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;
    }

}

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

问题

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

3 回答 3

4

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

至于你的问题:

  1. 您从哪里得知网站变得“不活跃”而 Gunicorn 必须再次加载该网站?那是垃圾。只要 Gunicorn 进程正在运行(即没有手动终止或因站点上的错误而终止),它就会保持完全初始化并准备就绪,无论是一个小时还是一个月。

  2. 你在这里砍树叶,不碰根。每个 Gunicorn 进程的内存使用情况并没有什么异常。它需要RAM 才能运行。您的问题是试图在功率严重不足的服务器上运行太多。没有优化可以在这里拯救你。您需要更多 RAM 或更多服务器。大概两者兼而有之。

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

  4. 没有办法可靠地知道哪些进程正在被交换。它每秒都在变化,取决于哪些正在积极运行并需要更多 RAM,哪些不活跃或根本不活跃。当您的服务器资源紧张时,它会花费一半的时间来确定接下来要处理哪个进程,尤其是当它们都处于活动状态并争夺资源时。

  5. 是的。Gunicorn 推荐 2*cores+1。所以在双核系统上,是 5;在四核上,9。但是,在这个系统上,您甚至无法为这些站点中的每个站点运行 5 个工作人员。您甚至无法可靠地为每个工作人员运行 1 个工作人员。

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

于 2012-05-01T19:46:22.463 回答
1

1)不知道你所说的不活跃是什么意思?如,被 nginx 禁用?还是工作太慢?

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

4)使用top:如何找出linux中哪些进程正在交换?

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

6) 是的,在 nginx 和应用程序级别。通过分析每个站点并提高其内存使用率,您可能会获得最大的好处(参见 2)。

于 2012-05-08T06:42:17.977 回答
1

关于:

关于您对 5 的回答,我认为 Gunicorn 的建议是矫枉过正。

我最近对工人数量进行了一些临时测试,发现假设您有足够的 RAM,那么 2*cores+1 的经验法则非常准确。我发现请求/秒几乎呈线性增长,直到我接近这个数字,然后随着操作系统开始抖动而下降。

由于结果很大程度上取决于工作负载,因此请尝试不同的值并查看您的性能峰值在哪里。

于 2012-05-09T10:48:30.510 回答