2

我在一个即将成为生产环境的环境中运行 Django/Tastypie,但是我注意到使用 Apache 与使用内置开发服务器相比有很大的开销。阿帕奇慢得多。

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

阿帕奇:

$ 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)

开发服务器(manage.py 运行服务器):

$ 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。有些事情似乎不对,因为与开发服务器的请求要快得多。

这是我的 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 开发服务器前 50% 的测试平均为 64 毫秒,尽管 apache 服务器的扩展性要好得多。是否有任何建议来调整 apache 以便它可以更快地服务于初始请求的范围?我不介意使用额外的服务器进行水平扩展,但请求时间对我来说意味着一切。

4

2 回答 2

1

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

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

我建议您观看我的两场 PyCon 演讲,其中包括 Apache/mod_wsgi 配置和使用性能监控来找出瓶颈所在。这可能会给你一些关于你为什么会遇到问题的背景信息。

于 2013-07-29T01:47:51.980 回答
1

你考虑过使用 NGINX 吗?它让我们在使用 uwsgi 运行时获得了显着的性能提升。

于 2013-07-29T09:04:27.603 回答