优化和扩展我的Web服务器(Nginx + Gunicorn + Django堆栈)

时间:2017-01-24 12:53:48

标签: python django nginx amazon-ec2 gunicorn

我们有一个运行Nginx和Gunicorn的Web服务器设置,它运行Django应用程序。曾经有一段时间我们获得了很高的负载并获得了大量的5XX。为了摆脱这种情况,我们立即增加了5次服务器数量,并重新启动了所有Gunicorn工作人员。 现在,我们的服务器仍未得到最佳使用,CPU使用的最大值为10-15%,内存相同(20-30%)。 因此,这不是一个永久的解决方案,如果我们使用更大和更多的服务器,它也会导致我们的停机时间和高成本。

为了研究这个问题,我们从负载测试开始。

当我们进行负载测试时,即使服务器上的资源几乎没用,我们也会开始收到5xx错误。

负荷测试结果

加载测试1

资源:1个带有Nginx的ELB 1服务器和4个gunicorn工作者在虚拟环境中运行Django。

使用Locust进行负载测试,它具有用户进入应用程序后将执行的完整工作流程。

1000个用户,增加10个

每秒请求数(失败前):120 CloudWatch上的最高CPU = 45%,服务器上升至100% 负载测试开始后,内存的使用量不超过2 GB。服务器有8 GB内存(RAM)

突然间,我开始收到错误。开始获取网关超时,无法连接到后端服务器。还有AWS ELB 5xx,然后服务器也停止服务。

加载测试2

资源:4个服务器,1个ELB,Nginx和4个Gunicorn工作人员在服务于Django的virtualenv中的每个服务器上运行。

1000个用户,增加10个

34 RPS,11%突然失败率然后停止获得200。 ELB服务器停止服务。总共29000个请求,2965个失败我相信然后都开始失败。请求大小约为140688 Bytes。开始获取网关超时,无法连接到后端服务器。

CPU再次没有超过20%的利用率。 负载测试开始后,内存的使用量不超过2 GB。服务器有8 GB内存(RAM)

负载测试3 资源:一个ELB下的11个服务器

直到80-200 RPS波动(每秒请求数) 开始获取网关超时,无法连接到后端服务器 服务器运行不健康

CPU再次没有超过20%的利用率。 负载测试开始后,内存的使用量不超过2 GB。服务器有8 GB内存(RAM)

加载测试4

资源:40台服务器 类似的结果。

调整开始

我在Nginx上配置的内容

允许每个工作人员接受1500个连接和微调fds,缓存,gzip,工作人员限制等。

对Nginx conf进行了以下更改:

Nginx worker processes are set to auto which is okay, I guess.
Nginx keepalive timeout is 65 which is high. 

open_file_cache max=200000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;

tcp_nopush=on     Send all the response in a simple packet.

keepalive_timeout 65;
types_hash_max_size 2048;
send_timeout 10;
sendfile on;    sendfile_max_chunk 512k;
worker_rlimit_nofile 10000;

Gzip设置如下:

gzip on;
    gzip_disable "msie6";

    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

难道我的Nginx正在接受连接而Gunicorn没有被优化是无法处理这些请求吗?

系统级

另外,我应该将系统级别更改为: sysctl net.core.somaxconn = 1024?现在,它是128.这是限制性问题吗?

我们正在使用的Gunicorn Command

exec gunicorn ${DJANGO_WSGI_MODULE}:application \
  -b 127.0.0.1:8000 \
  --name $NAME \
  --workers $NUM_WORKERS \
  --user=$USER --group=$GROUP \
  --log-level=info \
  --bind=unix:$SOCKFILE \
  --timeout $TIMEOUT \
  --backlog=2048

m4.large上的工作人员是4.超时和其他变量值:

SOCKFILE=/home/ubuntu/run/gunicorn.sock    # using this unix socket
USER=ubuntu                                   # the user to run as
GROUP=ubuntu                                  # the group to run as
NUM_WORKERS=4                              # how many workerprocesses should Gunicorn spawn
DJANGO_WSGI_MODULE=haptik_api.wsgi               # WSGI module name
PORT=8000
TIMEOUT=300

最终问题

  1. 我想知道我可以在Gunicorn中改变的方式和参数,以便我充分利用我的资源。我的服务器现在是4核8 GB RAM。
  2. 如何让Gunicorn使用更多内存和CPU,以便最佳地使用服务器。我可以调整什么?
  3. 是否需要进行系统级调整?像sysctl
  4. 我甚至尝试过m4.xlarge和m4.2xlarge以及t2.medium(服务器数量的4倍)
  5. AWS ELB也可以成为问题吗?它无法处理这些请求并且无法添加到浪涌队列中?
  6. 如何优化我的Nginx + Gunicorn + Django nonrel以接受更多连接并提高性能并优化资源利用率?
  7. 我应该为服务器设置什么样的SCALING POLICY?中央处理器?记忆?网络?或其他任何东西。 (问题是当负载增加时它们不会发生太大变化)。服务器在AWS上 - AWS EC2。
  8. 如果您需要更多详细信息,请与我们联系。

0 个答案:

没有答案