Django apache与内置开发服务器的重大开销

时间:2013-07-29 00:14:53

标签: python django apache wsgi tastypie

我正在即将推出的生产环境中运行Django / Tastypie,但是我注意到使用Apache而不是使用内置的开发服务器会产生大量开销。 Apache速度慢得多。

以下是使用ab的非科学带宽测试:

的Apache:

$ ab -n 100 -c 50 https://www.mydomain.com/api/v1/clock/?format=json
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking www.mydomain.com (be patient).....done


Server Software:        Apache/2.2.22
Server Hostname:        www.mydomain.com
Server Port:            443
SSL/TLS Protocol:       TLSv1/SSLv3,AES256-SHA,2048,256

Document Path:          /api/v1/clock/?format=json
Document Length:        295 bytes

Concurrency Level:      50
Time taken for tests:   1.313 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Non-2xx responses:      100
Total transferred:      49800 bytes
HTML transferred:       29500 bytes
Requests per second:    76.15 [#/sec] (mean)
Time per request:       656.634 [ms] (mean)
Time per request:       13.133 [ms] (mean, across all concurrent requests)
Transfer rate:          37.03 [Kbytes/sec] received

Connection Times (ms)
min  mean[+/-sd] median   max
Connect:       15  283 162.5    282     590
Processing:    55  324 148.4    306     622
Waiting:       55  319 150.2    305     621
Total:        110  607 138.8    619     712

Percentage of the requests served within a certain time (ms)
50%    619
66%    691
75%    692
80%    701
90%    709
95%    709
98%    711
99%    712
100%    712 (longest request)

Dev Server(manage.py runserver):

$ ab -n 100 -c 50 http://127.0.0.1:8000/api/v1/clock/?format=json
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient).....done


Server Software:        WSGIServer/0.1
Server Hostname:        127.0.0.1
Server Port:            8000

Document Path:          /api/v1/clock/?format=json
Document Length:        381 bytes

Concurrency Level:      50
Time taken for tests:   0.701 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      54500 bytes
HTML transferred:       38100 bytes
Requests per second:    142.59 [#/sec] (mean)
Time per request:       350.656 [ms] (mean)
Time per request:       7.013 [ms] (mean, across all concurrent requests)
Transfer rate:          75.89 [Kbytes/sec] received

Connection Times (ms)
min  mean[+/-sd] median   max
Connect:        0    1   1.9      0       7
Processing:    43   73  47.0     63     365
Waiting:       31   70  47.0     61     365
Total:         50   74  47.0     64     365

Percentage of the requests served within a certain time (ms)
50%     64
66%     67
75%     69
80%     71
90%     77
95%    101
98%    276
99%    365
100%    365 (longest request)

正如您所看到的,在较小的负载下,开发服务器的速度提高了约10倍。即使在较高负载下,它也会处理两倍的请求。

我已经完成了对Apache的基本修改,试图解决这个问题,这似乎有点帮助,但是还有其他我不知道的东西吗?我正在请求的'时钟'是一个非常基本的脚本,有一个直接的数据库调用,所以没有什么时髦的连接或任何事情。它使用Tastypie,因此输出是直接文本/ json。有些东西似乎不正确,因为使用dev服务器的请求速度非常快。

以下是我的Apache设置。它是在守护进程模式下的worker MPM上设置的:

KeepAlive Off

<IfModule mpm_worker_module>
    StartServers         25
    MinSpareThreads      25
    MaxSpareThreads     300
    ThreadLimit          64
    ThreadsPerChild      25
    MaxClients          300
    MaxRequestsPerChild   0
</IfModule>

WSGIRestrictEmbedded On

添加虚拟主机:

    WSGIDaemonProcess www.mydomain.com processes=4 threads=1
    WSGIProcessGroup www.mydomain.com
    WSGIScriptAlias / /var/www/domain/wsgi.py process-group=www.mydomain.com application-group=%{GLOBAL}
    WSGIPassAuthorization On

Python / Tastypie设置:

Debug = False
USE_I18N = False
USE_X_FORWARDED_HOST = True

它在负载均衡的AWS媒体实例上运行,并且此服务器不提供任何静态文件,例如images / css / js。我尝试在IOPS / x-large实例上增加此功能,但没有任何变化。数据库位于Amazon RDS上。但是在运行开发服务器时所有这些都是一样的,这告诉我托管环境不是问题。

任何帮助将不胜感激!!我此时并不担心高负荷。它是一个基于JSON的API,因此所有请求都是文本,非常小。我最担心的是来自高级别小请求的响应时间。

谢谢! 标记

编辑:

我在apache上做了一个新的ab测试,将dns映射到localhost。这与将其映射到127.0.0.1基本相同。这样可以获得更好的结果:

$ ab -n 100 -c 50 http://www.mydomain.com/api/v1/clock/?format=json
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking www.mydomain.com (be patient).....done


Server Software:        Apache/2.2.22
Server Hostname:        www.mydomain.com
Server Port:            80

Document Path:          /api/v1/clock/?format=json
Document Length:        381 bytes

Concurrency Level:      50
Time taken for tests:   0.666 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      55900 bytes
HTML transferred:       38100 bytes
Requests per second:    150.22 [#/sec] (mean)
Time per request:       332.841 [ms] (mean)
Time per request:       6.657 [ms] (mean, across all concurrent requests)
Transfer rate:          82.01 [Kbytes/sec] received

Connection Times (ms)
min  mean[+/-sd] median   max
Connect:        0    3   3.0      2       6
Processing:    38  258  92.6    308     357
Waiting:       33  254  92.9    303     354
Total:         44  261  90.6    310     363

Percentage of the requests served within a certain time (ms)
50%    310
66%    321
75%    323
80%    327
90%    336
95%    344
98%    362
99%    363
100%    363 (longest request)

因此,初始测试是通过外部负载均衡器进行的。这些数字还可以,但是,前50%的测试平均响应时间为310毫秒。这些似乎与我的实时外部测试相当。但是,django dev服务器首先50%测试平均64ms,即使apache服务器扩展得更好。是否有任何建议来调整apache,以便它可以更快地落入服务初始请求的范围内?我不介意使用其他服务器进行水平扩展,但请求时间对我来说意味着一切。

2 个答案:

答案 0 :(得分:1)

您的Apache MPM配置以各种方式被破坏,并且对于您实际允许流向应用程序实际运行的mod_wsgi守护程序进程组的请求数量也是过度的。在负载下,您要做的就是创建大量的积压和长响应时间,因为您的Django应用程序无法跟上,因为它缺乏处理负载所需的进程/线程。

使用ab只有100个测试请求也会使结果失真,因为您可能会为Apache测量预热时间,因为它会创建更多的工作进程。最初,您还将计算Django应用程序的加载时间。

我建议你观看我的两个PyCon演讲,其中包括Apache / mod_wsgi配置和使用性能监控来解决瓶颈问题。这可能会给你一些关于你遇到问题的背景。

答案 1 :(得分:1)

你考虑过使用NGINX吗?它使我们在使用uwsgi时能够显着提升性能。