Django性能测试?一个现实世界的例子
作者:网络转载 发布时间:[ 2014/7/2 14:42:50 ] 推荐标签:性能测试 测试技术
测试哪个页面?
考虑到这一点,我们测试了网站的两个网页:
主页: 对主页的匿名访问
“墙”: 对某个“墙”已认证访问,该网页包括从数据库获取的内容
事实静态与高度动态
对于匿名用户来说,主页基本上是静态的,它只是简单的渲染某个模板而无需数据库的任何数据。
“墙”页面则非常动态,包括了从数据库获取的主要数据。该模板在被渲染时,针对不同时区用户的日期设置“删除”了指向某些物件的链接,等等。某些“墙”包含了大约50个物件,在被优化前,大约要发起 80 条数据库查询。
第一次测试时,我们运行了两个可以从 Django 接受请求 FastCGI 后端。
Home: 175 req/s (即每秒请求数量)Wall: 8 req/s.
经压缩的内容
第一个配置优化是使用 GZipMiddleware 激活输出的 gzip 压缩。性能轻微提高,没有大的变化。但无论如何为了节约带宽,这么做还是值得的。
Home: 200 req/s.
Wall: 8 req/s.
更多进程,更短的队列
然后,我们将 FastCGI 后端的数量从 2 个提升到 5 个。这项改进减少了 500 响应的数量,因为更多的请求可以由额外的后端来处理。
Home: 200 req/s.
Wall: 11 req/s.
更多的进程,更多的问题
从 2 到 5 的改进非常不错,因此我们决定将 FastCGI 后端数量提升到 10 。性能却显著地 下降 了。
经查看服务器上的 vmstat ,可以看到原因是出现了内存交换。太多的进程,每个都为 Python 使用了内存,导致 VPS 内存耗尽,从而不得不从硬盘往返交换内存。
Home: 150 req/s.
Wall: 7 req/s.
基于此,我们将 FastCGI 后端数量降回 5 以进行更多测试。
分析——时间耗到哪里去了
“墙”页面的性能令人失望,因此我们开始进行优化。我们所做第一件事情是分析代码以确定时间都被花费在何处。
使用一些简单的 分析中间件 之后,很清楚地发现时间被消耗在数据库查询之上。“墙”页面包括许多查询,且数量与其所包含的物件数量呈正比。测试墙页面上引发了大约 80 个查询。毫无疑问其性能是糟糕的。
进行优化
通过优化物件附加媒体的处理方式,我们直接给每个物件剔除了一次查询。该措施稍微地减少了请求所需时间,因此也提高了每秒可处理的查询数量。
Wall: 12 req/s.
导致低效的另一个原因是无论页面是否被请求,对每个物件的内容都应用了多个过滤器(Filter)。经我们修改,被过滤内容的 HTML 输出都被存储在物件当中,节约了页面被查阅时的需要进程。这又带来一点小小改进。
Wall: 13 req/s.
通过减少数据库查询,我们以修改用户配置文件(用于显示是谁将该物件粘贴到墙上)的获取方式为每个物件剔除了一次查询。这次修改又提高了不少。
Wall: 15 req/s.
这场测试的后一次优化目标是减少获取物件所附加媒体的查询数量。我们再一次削减了一些查询,稍微地提高了性能。
Wall: 17 req/s.
下一步:缓存
在尽可能地减少查询之后,接下来要进行一些缓冲工作。获取缓存数据通常比查询数据库更加快捷,因此我们期待性能有一个显著提升。
对整个页面的输出进行缓存是没有意义的,因为每个页面根据发出请求的用户不同而截然不同。只有当用户对同一页面的两次请求之间,情况没有发生任何变化,才可能出现缓存命中。
对墙、物件及用户的列表进行缓存的作用更大。被缓存的数据将被用于从同一用户发出的多个请求,及在对于墙壁的不同程度和不同用户访问之间共享。这未必是巨大的胜利,因为每个“墙”很可能只有极少数的用户,而数据必须在高速缓存中停留足够长的时间以被别人获取。
在这种情况下,我们简化的 httperf 测试将会被极大地误导。每个请求都由同一用户发出,因此缓存命中几乎是,而性能将因此极高!这反映不出真实世界的站点使用情况,因此我们好进行一些更好的测试。
目前我们还没有使用缓存,因为站点可以轻松地应对的当前活动水平,但一旦 Hey! Wall 流行起来,这将是我们的下一个步骤。
多少用户能够导致每秒17次请求?
提供每秒 17 次请求相应看起来仍然非常少,但将该数据翻译成站点的实际用户量是非常有趣的事情。显然,这数据不包括提供像图片、CSS 和 JavaScript 文件之类的媒体文件服务。相对来说,媒体文件个头要大一些,但它们直接由 Lighttpd (而不是 Django)处理,并提供了 Expires 头部信息来允许客户端对它们进行缓存。不过,为了在测试中更好地进行评估,我们还是需要对服务器进行一些处理。
现在说采用何种通用模式还为时过早,因此我说的只能是猜测。请允许我这么说!
我将假定每个用户平均访问三个“墙”,并按顺序查看它们的内容,暂停10至20秒时间以阅读新的评论,或查看一些照片和打开一些链接。该用户每天进行三次这种操作。
只看墙页面,不看媒体的话,用户将每天对墙页面发起 9 次访问请求。每个用户一次只能发起一次访问请求,因此在时间上,任何一秒内 17 个用户可以同时进行该操作。一分钟内,用户只发出3次访问请求,因此17个并发用户只用去了60 秒中的 3 秒(或20秒中的1秒)。
如果一段时间内用户的请求分布是完全平衡的(提示:不可能的!),那也意味着每分钟可以有 340 用户(17 * 20)访问该网站。延续这个不真实的例子,我们可以说每天有 1440 分钟,而每个用户每天访问网站 3 分钟,因此该网站可以应对大约 163,000 个用户。这对于一个每月 20 美元的 VPS 来说已经非常棒了!
为了更多统计一下这些数字,让我们假定每天6小时内,我们每分钟应对 200 个并发用户,另 6 个小时内(每分钟)应对 100 个并发用户,剩下的 12 小时内(每分钟)应对 10 个并发用户。基于每秒 17 次请求的大负荷,网站每天仍然可以应对的大约 115,000 个用户。
我确信这些数字并不虚假和荒谬。如果有人在评论中提出更好的评估方案或者真实世界的数据,我将非常感兴趣。
我们学到了什么?
概括:
测试网站性能可能会产生令人惊异的结果
过多的数据库查询对性能(duh)来说不是件好事
对站点的某类内容进行缓存比对其他一些更好
一台廉价的 VPS 所能应对的用户数量比你所想像的要多得多
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11