第5章 Web性能测试方法
良好的开始是成功的一半。小白所在公司网站的代码编写的差不多了,安放服务器的机房也已经找好,只要等第4章选购的服务器正式到位,就可以上机架、部署测试版本网站进行试运行了。离部署测试版的日子还有一段时间,小白对现在这段短暂的空闲,做了如下的安排:
首先要熟悉性能测试的几种方法。
在第4章CPU和硬盘的基础上,熟悉常见操作系统的性能计数器特点,并在自己的电脑上进行一次手工的性能测试。
熟悉常用的几种性能测试软件,听说有Load Runner等,从中选择一个比较好的,毕竟这也是部门经理在第4章开头布置的任务之一。
这3点内容将分别在从本章开始的第5章、第6章和第7章中讲述。现在就开始介绍Web性能测试的一些方法。
5.1 Web性能测试的目的与方法
本节首先介绍测试的目的,然后会介绍最常见的9种Web性能测试的方法,希望读者通过这些方法,对性能测试有深度的认识。
5.1.1 Web性能测试的目的
进行Web性能测试的目的很简单:
获得Web应用的性能表现情况。
发现并验证、修改Web应用中影响性能的Bug。
为网站性能优化提供数据参考。
实际所做的一切测试工作都要围绕这3个目的来进行,这样才不会在出现这样或那样困难的时候迷失方向,导致资源浪费。
5.1.2 Web性能测试方法的先决条件
对于性能测试方法,在某种意义上说,就是性能测试的分类。不同的性能测试分类,决定了需要采用不同的性能测试方法。Web性能测试也是如此。
不过在介绍具体的分类或者方法之前,有必要强调一下进行Web性能测试的先决条件。其实,从前面的章节,我们已经能够发现,进行Web性能测试的先决条件有这样几条:
一个稳定的Web应用版本。该版本必须与投入生产环境的版本极其类似。这一点的原因在前文也介绍过,对一个最终不会上线运行的版本,或者功能没有完成的版本进行性能测试是没有多大意义的,除非为了演练性能测试方法本身。
性能测试所处的测试环境,必须独立于开发环境,并且尽量类似于实际生产环境。这一点也很重要,测试环境必须是可比较的,大致拥有相同的参照物(比如CPU、硬盘速度等),这样的测试结果才更有参考价值。
当然,小白在今后这3章所做的性能测试,是为了在个人电脑上方便快速地了解性能测试方法,熟悉性能测试软件,并不打算将测试报告发送出去形成结果。对于小白和我们一般的初学者,这不失是一个好的学习方法。但是,在真正的性能测试工作中,对于上面的两个Web性能测试(也可以推广到所有的软件性能测试上面),一定要记牢。
下面将介绍Web性能测试方法的具体内容。
5.1.3 Web性能测试的详细分类
在第2章中曾粗略地讲到性能测试包含性能测试方法(狭义的)、压力测试等,现在可以将绝大部分文档中提到的众多分类列举出来了,它们是如下9种:
性能测试(Performance Testing);
压力测试(Stress Testing);
负载测试(Load Testing);
并发测试(Concurrency Testing);
配置测试(Configuration Testing);
耐久度测试(Endurance Testing);
可靠性测试(Reliability Testing);
尖峰冲击测试(Spike Testing);
失败恢复测试(Failover Testing)。
看起来分类很多,但它们实际上都是为了性能测试的目的:考察应用对于系统性能的影响状况。因此,它们的区别只在于考察系统性能的角度不同。角度决定方法,这正是本节开始时将性能测试方法和性能测试分类基本划等号的原因。
5.1.4 性能测试(Performance Testing)
在介绍性能测试具体方法之前,首先说明一下性能测试(总称)和性能测试(方法)的区别。我们也分别把它们叫做广义性能测试和狭义性能测试。
【广义性能测试与狭义性能测试】
广义性能测试包括前述所有分类或方法,以考察Web应用对于系统性能影响状况为目的的测试活动。而狭义性能测试则是其中的一个小分类,为了区别广义性能测试中的其他分类。这种测试也是广义性能测试中最基本的方法之一。利用第一章所讲过的维恩图,广义性能测试和狭义性能测试之间的关系如图5-1所示。
图5-1 广义狭义性能测试的包含关系
听起来有些混淆,但对于我们要从事实际工作的人来说,名词并不重要,只需要知道有性能测试这样的总称(广义),还有性能测试这样的方法(狭义)即可。在看相关参考文献的时候,根据上下文一般能很容易判断出当前所指的性能测试是狭义还是广义。
本书中凡是"Web性能测试"这样的字眼,都是指的广义性能测试,特此说明。
【性能测试】
性能测试(英文名称也是Performance Testing)是这样一种方法:它通过模拟实际生产环境中运行的软件平均业务量,测试系统的性能是否满足设计说明书中的性能要求。性能测试方法在所有前述9种方法中是一种最基本、最常见的测试方法。这就是说,它是实施性能测试所必须进行的一种方法。
5.1.5 小白的第一次性能测试
为了尽快熟悉这种方法,小白决定利用自己电脑和公司网站的测试版本来做一次手工性能测试的实践。
一般来说,在网站尚未上线的期间内,网站的技术部门都会维护一个或几个网站的测试版本,方便开发工程师和测试工程师开展工作。即便是网站上线以后,也会继续维护这样的网站,以方便网站每日更新时的调试,待没有问题后再正式上传到生产环境中。这种结构如图5-2所示。
图5-2 网站正式版本与测试版本关系示意
对于小白的第一次性能测试,该如何选择测试所针对的网站版本呢?有两点需要考虑:
由于网站正式版本尚未发布,目前还没有正式版本可供选择。
即使正式版本发布也不能直接使用它来测试(因为这样会影响用户的使用)。
根据以上两点,选择图5-2中的稳定测试版本。
截至目前为止,小白所知道的仅仅是打开网站的响应时间,所以他想从这个时间入手,来评估一下网站测试版本的性能。他是这样进行测试的:
打开浏览器,输入网站测试版本的网址,按下Enter键,并记录此时的机器时间。
在网站全部打开后再记录一次当前机器时间。
两者相减,得到一个时间间隔。
重复多次,最后计算平均时间间隔。
对比网站的设计说明书,在那里一般都会有以响应时间为标准的性能要求。
根据两者数值的比较,决定网站测试版本的性能好坏。
【有关时间的记录】
在性能测试过程中,往往免不了进行当前时间的记录,或者计算两个时间的差值。由于Windows系统任务栏中的时间数字较小,读者可以在互联网中寻找一些显示桌面时钟的免费软件(显示时间最好可以包含秒数以达到精度要求)。当然,这样的时间记录是依赖于肉眼,精度依然不够高。可以通过编程的方法来获得更精确的时间。
虽然小白所列出的上述测试过程看起来与用户浏览网站没有什么不同,而且,也看不到使用哪些高级的工具软件,但它确实是一次人工的性能测试。性能测试真的都是这么简单吗?小白非常好学,进而思考了下列几个问题。
5.1.6 小白的思考
在第3章中我们已经知道响应时间,并且知道用户所感觉的响应时间并不很准确。那么,小白这次测试应用了计算机时间等"高科技"计时装备,是否就意味着准确呢?
1.响应时间的问题
其实,对于感觉和记时两种方法,响应时间数值都是差不多的。那么,访问Web应用,多长的响应时间说明性能比较好呢?实际上依赖于几条标准。
软件设计说明书中的标准:根据用户的需求,一般都会列出。
不成文的习惯标准:如果在设计说明书中没有列出,那么可以参考国外的业内公认标准,即3/5/10原则。
在3秒钟之内,页面给予用户响应并有所显示被认为是"不错的"。
在3~5秒钟内,页面给予用户响应并有所显示被认为是"好的"。
而5~10秒钟是可以"勉强接受的"。
超过10秒钟就有点让人不耐烦了,用户很可能不会继续等待下去。
在尽可能合理的情况下,响应时间应该越快越好。
另外,响应时间包含了网络传输数据的时间、DNS记录查找时间和真正由网站服务器处理的时间,因此,遇到时间间隔很长的情况时,首先要排除前两个时间的影响。
另外,还有很重要的两点不能忽略:
小白只是以一个用户的身份去访问网站的测试版本,而网站一旦投入使用,真实情况是会有上万人同时访问它,那么响应时间还会有现在这么好吗?
小白是在公司内部进行测试的,要知道公司内部的局域网一般都是百兆、千兆网,速度非常快;如果换到家里,用ADSL之类的上网条件,响应时间还会如此快吗?
这几个问题都说明小白的这次性能测试确实欠缺很多因素。不过,这正是我们在下面的章节要学习的。
2.测试场所和指标的问题
小白在进行测试的时候,记录的是自己电脑上的时间间隔,从它数值的大小来间接判断服务器端性能的好坏。那么,能不能直接获得服务器端的性能数据,岂不是更加精确吗?
是的,完全可以。响应时间所带给人的只是性能好坏的大概印象,如果要更加专业的测试性能,需要获取服务器端的指标数据,我们管这些指标叫做性能计数器(Performance Counter),在第6章,我们将重点介绍它们的单个含义以及获取方法。
综上所述,小白基于目前理解的第一次性能测试有了结果,虽然过程远远不够,但也让我们体会到了性能测试所关注的要点,进行的大致过程。简单地说,Web应用的性能测试方法,就是通过模拟若干用户对于网站的访问,获得性能计数器和其他指标的数据,再分析它们以进行性能评估,使得关注性能测试的各方对系统性能有基本的认识。
5.1.7 压力测试(Stress Testing)
相对于前面性能测试方法的普通,压力测试(Stress Testing)方法可以说走了一个极端。它测试Web应用在事先规定的某种饱和状态下,比如CPU处于75%利用率的情况下,系统是否还具备处理业务的能力,或者系统会发生什么样的状况(出现错误?系统宕机?等)。
一句话,压力测试是考验一个系统的抗压能力的:在当前比较大的压力下,它能否承受得住。压力测试的目的是为了测试Web应用的稳定性。
【压力测试与体操比赛】
在体育比赛场上我们可以看到生活中的压力测试,例如体操比赛中的规定动作环节。场上选手在比赛时,其动作组合必须包含组委会所设定的所有规定动作,如图5-3所示的经典规定动作--托马斯全旋。通过在这样的条件下比赛,裁判来考察运动员的完成质量,由于动作难度系数基本一致,重点将是完成质量的稳定性。通过这个类比,压力测试就很好理解了。
图5-3 类似压力测试的体操规定动作比赛(图中动作为托马斯全旋)
压力测试方法有如下的两个特点:
(1)压力测试方法的目的是测试系统(本书中为Web应用)的稳定性。人们对很多软件系统都有这样一个经验:当系统处于较大压力的时候,如果还能够维持正常工作,那么,就能说明它在压力不大的一般条件下,具有长时间正常工作的能力。从这里可以看出,压力测试方法有一点“一叶知秋”、“以小见大”的含义在其中。
(2)压力测试方法的具体操作过程是通过对系统施加负荷(模拟用户对Web应用的访问等),使系统的资源占用保持在一个事先约定的水平(比如前文所提到的CPU占用率75%),来检验此时系统的表现。测试的重点在于系统对于用户的响应时间变化、系统是否出现错误甚至崩溃等。
5.1.8 负载测试(Stress Testing)简介
在实际工作中,负载测试方法和压力测试方法往往被放在一起谈论,因此很容易混淆,其实它们的区别是很明显的。
【负载测试方法】
负载测试(Load Testing)方法通过在被测试系统上不断增加负荷,直到事先选定的性能指标(比如响应时间),变为不可接受或系统的某类资源使用已经达到饱和状态。负载测试方法实际就是一个不断加压,直到找到系统不可用临界点的过程,形象地说,那一点正是“强弩之末”。
【负载测试方法与举重比赛】
在5.1.7节我们把压力测试和体操比赛的规定动作相类比,在这里我们将负载测试方法类比为举重比赛,如图5-4所示。在比赛中,选手不断地增加重量,挑战自己的极限,直到杠铃加到某一个重量时,3次试举都失败。这一重量就是举重比赛的最终结果。
图5-4 举重比赛与负载测试有相同之处
通过负载测试方法,我们可以发现系统的处理极限点在哪里。
5.1.9 负载测试的特点
负载测试方法有如下几个特点。
(1)它的主要目的在于找到系统处理能力的极限,为系统进一步优化做参考。另外,这种测试也可以用来比较不同的优化方法对于性能极限的提升,因此也可以称之为可扩展性测试(Scalability Testing)。这个名词可以用图5-5清晰地表述出来。
在图5-5中,2条曲线分别代表两种优化方法经历负载测试的结果。A方法的性能极限在A点,B方法的性能极限在B点。根据负载测试的定义,比A、B两点值小的部分都是系统的安全运行区间。由于B的数值要大于A,说明采用B方法优化,系统的可扩展性提高了。
图5-5 负载测试用于优化方法的比较:B好于A
(2)负载测试方法的操作是一个不断加压的过程。负载测试方法是一个"性能指标记录--增加负荷"的操作循环,直到预定被关注的性能指标不再令人满意。这个极限点在测试结果中的表示类似这样的形式:"在给定条件下当前Web应用将最多允许10000个并发用户访问"、"在给定条件下当前Web应用最多能够在1分钟内处理1000次用户对数据库的修改"等。常见的在负载测试方法中被关注的性能指标包括:Web应用的响应时间、Web服务器平均CPU利用率等,它们的具体数值需要根据实际情况来调整。
(3)负载测试方法要考虑被测Web应用的实际业务负荷量与正确的使用场景,以保证测试结果具有参考价值。
【实战演练:教训】
在这方面,笔者的同事曾经有一个教训。有一个网站,可以通过Web直接访问,也可以通过RSS进行订阅。在网站发布之前,网站技术部门的所有工程师都认为绝大部分用户都是通过Web来访问的,因此,在时间紧迫的情况下,重点测试了Web访问的性能,对于RSS相关代码测试的就很少。结果在网站上线之后,他们惊奇地发现,大部分用户访问都是通过RSS来完成的,因为负载测试做的很简略,结果每过多久服务器就被拖的几乎无法访问了。可见,对于负载测试,乃至整个性能测试而言,模拟真实的应用场景是多么的关键。
(未完待续)
相关链接:
捉虫记--大容量Web应用性能测试与LoadRunner实战(连载一)
捉虫记--大容量Web应用性能测试与LoadRunner实战(连载二)
捉虫记--大容量Web应用性能测试与LoadRunner实战(连载三)