关于Django/uwsgi性能?

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

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

下面是我运行uwsgi的方式:

sudo uwsgi -b 25000 --chdir=/www/python/apps/pyapp --module=wsgi:application --env DJANGO_SETTINGS_MODULE=settings --socket=/tmp/pyapp.socket --cheaper=8 --processes=16  --harakiri=10  --max-requests=5000  --vacuum --master --pidfile=/tmp/pyapp-master.pid --uid=220 --gid=499

nginx配置:

server {
    listen 80;
    server_name test.com

    root /www/python/apps/pyapp/;

    access_log /var/log/nginx/test.com.access.log;
    error_log /var/log/nginx/test.com.error.log;

    # https://docs.djangoproject.com/en/dev/howto/static-files/#serving-static-files-in-production
    location /static/ {
        alias /www/python/apps/pyapp/static/;
        expires 30d;
    }

    location /media/ {
        alias /www/python/apps/pyapp/media/;
        expires 30d;
    }

    location / {
        uwsgi_pass unix:///tmp/pyapp.socket;
        include uwsgi_params;
        proxy_read_timeout 120;
    }

    # what to serve if upstream is not available or crashes
    #error_page 500 502 503 504 /media/50x.html;
}

得到以下结果:

Nginx版本:Nginx版本:Nginx/1.2.6

Uwsgi版本:1.4.5

Server Software:        nginx/1.0.15
Server Hostname:        pycms.com
Server Port:            80

Document Path:          /api/nodes/mostviewed/8/?format=json
Document Length:        8696 bytes

Concurrency Level:      100
Time taken for tests:   41.232 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      8866000 bytes
HTML transferred:       8696000 bytes
Requests per second:    24.25 [#/sec] (mean)
Time per request:       4123.216 [ms] (mean)
Time per request:       41.232 [ms] (mean, across all concurrent requests)
Transfer rate:          209.99 [Kbytes/sec] received

在500并发级别上运行时

oncurrency Level:      500
Time taken for tests:   2.175 seconds
Complete requests:      1000
Failed requests:        50
   (Connect: 0, Receive: 0, Length: 50, Exceptions: 0)
Write errors:           0
Non-2xx responses:      950
Total transferred:      629200 bytes
HTML transferred:       476300 bytes
Requests per second:    459.81 [#/sec] (mean)
Time per request:       1087.416 [ms] (mean)
Time per request:       2.175 [ms] (mean, across all concurrent requests)
Transfer rate:          282.53 [Kbytes/sec] received

提问于
用户回答回答于

1. ~~The CPU cost of each request is high in Django (which is highly unlikely given the low CPU value from the debug toolbar)~~
2. The OS is task switching a lot (especially if the load average is higher than 4-8), and the latency is purely down to having too many processes.
3. ~~There are not enough DB connections serving the 16 processes so processes are waiting to have one come available. Do you have at least one connection available per process?~~
4. ~~There is~~ ~~_considerable_~~ ~~latency around the DB, either~~:
    1. ~~Tens of small requests each taking, say, 10ms, most of which is networking overhead. If so, can you introducing caching or reduce the SQL calls to a smaller number. Or~~
    2. ~~One or a couple of requests are taking 100's of ms. To check this, run profiling on the DB. If so, you need to optimise that request.~~

因此

  1. Django看起来很好
  2. 负载测试的并发性(100或500)与进程(16)之间的不匹配:您将过多的并发请求推到系统中,以获取要处理的进程数量。一旦超过进程数,所发生的一切就是延长Web服务器中的HTTP请求队列
  3. 延迟很大,所以
1. Mismatch between processes (16) and CPU cores (1): If the load average is >3, then it's probably too many processes. Try again with a smaller number of processes
    1. ~~Load average > 2 -> try 8 processes~~
    2. ~~Load average > 4 -> try 4 processes~~
    3. Load average > 8 -> try 2 processes

1. ~~If the load average <3, it may be in the DB, so profile the DB to see whether there are loads of small requests (additively causing the latency) or one or two SQL statements are the problem~~ 

用户回答回答于

当向您的应用程序发送500个并发请求并且无法处理此类负载时,每个后端上的侦听队列都会很快填充(默认情况下为100个请求),可能希望增加该请求,但如果工作人员无法处理请求快速侦听队列(也称为积压)已满,Linux网络堆栈将放弃请求,并且将开始出现错误。

扫码关注云+社区