- 为什么要进行性能测试呢? 有些问题是只有在大并发或者压力测试下才会暴露出来的,在平常的公司内部测试中,感觉一切都是正常的,但是把服务放到生产线上,例如某个时刻突然有很多的用户要向我们的服务发送请求,这时候就考验到我们的服务是否会死锁,内存泄漏,能否在一个可接受的范围内响应,会不会crash,能否处理所有的请求(或者允许损失一定量的请求,比如1%内)等。为了不给用户糟糕的体验,所以我们需要在服务上生产线之前就要做好性能测试,但要做好性能测试,除了编写正确的性能脚本外,也需要分析很多因素的(主要有3大块:负载机、网络、被测系统),所以我希望自己能从平常中的点滴开始积累然经验后不断扩展。 在性能测试开始之前,是要保证你所要测试的场景中所涉及到的功能测试都已经能跑通,要不然到时候你会崩溃的QAQ
- 要做一个完整的性能测试要有哪些步骤?
– 1. 虚拟用户脚本编写(模拟用户实际操作)
– 2. 场景设计&运行(例如要5000个用户同时登录到会议室)
– 3. 分析结果报告
- 如何选择性能测试工具?
– 1. 只选对的,不选贵的。我的意识是根据自己所测的服务器对外提供了什么协议类型的API来进行相应的选择,比如我所处的平台新服务器对外提供了HTTP协议的API和基于SessionManager的TCP协议的API。关于HTTP协议的压测工具倒是有很多的,大家自己百度下,但是关于能测TCP协议的压测工具,我知道的并且会使用的并不多,只知道可以用能支持socket协议的压测工具来实现
– 2. 选的测试工具能按自己希望的步骤来编写虚拟用户脚本(而不是根据测试工具提供的录制步骤来完成虚拟用户脚本)
– 3. 有良好的场景设计功能
– 4. 有易于查看的输出报告
– 5. 有中文文档以及google或者百度等上能搜索到较多的疑问解答
综上所述,我选择了Loadruner作为我平台服务器初期的性能测试工具,而且loadrunner提供类C语言的脚本编写(我们在大学都应该学过C/C++,有一定的基础能帮助我们更快的熟悉脚本编写)。但是由于loadrunner不易于扩展,是商用工具,要想免费使用只能用loadrunner11版本的破解版,loadrunner11是很早之前的版本,对于一些新功能是无法支持的(例如:我们开发提供了一个SDK的DLL,在LR11中无法加载运行,但在LR12中可以加载运行)。总之工具只是帮助我们完成任务的,要想更好的完成任务,我们就需要不断的探索更多的解决办法(以后我会分享其他的开源性能测试工具或者如何自己编写一个适合我们被测系统的压测代码)
- Loadrunner的使用
– 下图显示的是LR的3个主要组件,其中Virtual User Generrator是用来编写虚拟用户脚本的
– Controller是用来设计场景的
– Analysis是用来分析运行数据,生成结果报告的
– 结合我实际工作中的项目来演示如何使用这3个组件的
Virtual User Generator
由于我们要自己来设计脚本执行的流程顺序,暂时使用不到loadrunner提供的录制功能,所以打开Virtual User Generator,点击New Script然后选择一个通用的协议,例如Web(HTTP/HTML)后点击Create按钮,经过这些步骤后,就为我们提供了一个初步的编写脚本用的模版了
• Virtual User Generator
– 虚拟用户脚本的设计是要考虑到典型场景的,例如一个会议室登录多个用户、多个会议室登录多个用户等等,接下来的demo将是针对一个会议室登录多个用户的场景的。先上图再逐一分解
– 与最初创建的模版相比,发现上图左边的工程区里面多了cJSON.h和JsonDemo.dll2个文件,由于LR支持加载纯C编译的DLL,所以我们就可以像使用python那样import XX包进来,然后直接使用其中的方法来帮助我们编写脚本,关于cJSON.h和JsonDemo.dll2个文件这2个文件的作用,将在接下来的脚本分析中说明吧
先上2张我实际写的项目脚本,为下面的解析提供依据:
Login_CreateGroup脚本:
- Virtual User Generator
– 如何找到纯C的源程序,然后编译成dll,最后导入到loadrunner中为我们所用?就拿刚刚的JsonDemo.dll来说明吧
– 1. 登录到Json的官网(www.json.org),找到C的源码然后下载
– 2. 打开Visual Stutio,New一个空的project,选择Visual C++下的Win32 Console Application,然后把Application Type选择为DLL
– 3. 右键点击Header Files,Add一个Existing Item…把刚刚下载的C的源码里面的cJSON.h添加进来,同样右键点击Source Files, Add一个Existing Item…把刚刚下载的C的源码里面的cJSON.cpp添加进来
– 4. Build Solution生成DLL(编译过程中如果有安全提示的话,可以在command line中输入/D “_CRT_SECURE_NO_WARNINGS” 来解决)
platfrom_room脚本:
- Controller
– 虚拟用户脚本已经编写好了, 但是虚拟用户脚本只是代表一个用户的某种行为,要想实现并发操作,那就是要模拟很多用户(例如2000个用户)的相同操作。
– 在真正的实际设计场景前,有几个概念需要理解下,什么是“系统用户数”、“在线用户数”、“并发用户数”?举一个例子来说明下, 假设有一个综合性的网站,用户只有在注册后登录系统才能够享有新闻、论坛、博客、免费信箱等服务内容,通过数据库统计知道了系统的用户数量为4000人,4000即为“系统用户数”;通过操作日志可以知道,系统最高峰时有500个用户同时在线,这里“在线用户数”即为500;这500个用户的需求肯定是肯定是不尽相同的, 有的人喜欢看新闻、有的人喜欢写博客、收发邮件等。假设70%的人在看新闻,10%的人什么也不干,剩下的20%的人写博客(收发邮件或者不停的跳转页面),那么真正对服务器造成压力的就是这500人中的20%(100人)。那么如何估算“并发用户数”?
– (1)C=nL/T (2) C1=C+3 √3
– 在公式(1)中,C是平均的并发用户数;n是login session的数量;L是login session的平均长度;T是考察的时间段长度。
– 在公式(2)中,C1是并发用户数的峰值,C就是公式(1)中的得到的平均的并发用户数。该公式的得出是假设用户的login session产生符合泊松分布而估算得到的
– 下面给出一个实例来讲述公式的应用。假设有一个OA系统,该系统有3000个用户,平均每天有大约400个用户要访问系统,对一个典型用户来说,一天之内用户从登录到退出系统的平均时间为4h,在一天之内,用户只在8小时之内使用该系统。带入公式(1)得到C=400*4/8=200,那么C1=200+3* √200=242
– 除了上述方法外,还有一种更为广泛但精度比较差的根据经验的方法,相应的经验公式为:C=n/10和C1=r*C。通常用访问系统用户最大数量的10%作为平均的并发用户数量;并发用户数的最大数量可以通过在并发数上乘以一个调整因子r得到,通常r的取值为2~3。
– 当然在我实际测试过程中的话,我是根据负责人要求的来进行并发测试,比如我主管说服务器要支持5000的并发请求,那么我就按照5000来设计了,等服务上线后,我会查看日志、数据库然后运用上面的公式再来分析每个阶段实际的并发用户数。
- Controller
– 1. 打开Controller,会出现一个“New Scenario”对话框,把刚刚编写好的”Login_CreateGroup”和”platform_room”这2个脚本添加到“Scripts in Scenario”。为什么要添加2个脚本,而不是在一个脚本中把我们要操作的步骤全部编写好呢? 这就有点像写代码,我们会把一些经常要用的且能共用的弄成一个库,那样谁要用的时候就直接引入这个库,会提高效率。所以在设计我平台服务器的性能脚本时候,我就尽量把每个接口都各自编写成脚本,然后在场景设计中就把这些脚本进行组合。
– 2. 这里介绍下“Schedule by”中的2个重要选项“Scenario”和“Group”,Scenario(场景):当你按场景进行计划时候,Controller将会同时运行所有参与场景的Vuser组,也就是说,定义的场景运行计划同时应用与所有Vuser组,而Controller将每个操作按比例应用与所有Vuser;Group(组):当你按Vuser组进行计划时,参与场景的每个Vuser组按其自己单独的计划运行,也就是说,对于每个Vuser组,你可以指定何时开始运行Vuser组,更直白一点的说,就是当Vuser组和Vuser组之间有依赖关系的时候,就用Group方式。
– 3. 接下来就说说我设计的场景,根据业务我需要先登录验证(会返回token),创建分组(会返回groupid),然后请求分配服务地址和登录会议室,所以呢,我只需要登录和创建分组一次,就能拿到后续登录会议室需要的token和grouip,于是我只要运行脚本“Login_CreateGroup”一次,然后再运行脚本“platform_room”很多次就能实现“一个会议室同时登录很多人”的场景,而且这里需要注意的一点是,这2个脚本是有依赖关系的,“Login_CreateGroup”是要在“platform_room”前面先执行完后,“platform_room”才能执行的。对应到Controller里面的设置如下图:
- Controller
– 4. 场景设计完了, 接下来就可以执行了, 但是我们性能测试不单单只是给被测系统加压, 我们还要关注整个测试过程中产生的数据, 然后选出我们所关心的数据,为进一步分析定位问题提供帮助。所以呢, 在开始RUN之前,我们先添加一下自己关心的,要监控的数据,下图是我监控的一些数据:
- Controller
– 5. 接下来就可以RUN了, 在Running过程中可能会遇到一个问题就是loadrunner卡在那边不动了, 然后后面的case都失败了, 通过观察监控的“Windows Resources”发现某一时段内CPU达到100%了,究其原因发现是因为设置太多的Vusers了(比如5000),这时候负载机因为自身的资源条件限制而引起的,为了解决这一问题,我们可以采用loadrunner的分布式加压来解决。
– 什么是分布式加压呢? 分布式加压其实就是用另外一台负载机来帮助我们实现一定量的Vusers,那么我们就需要在另一台负载机上安装loadrunner11软件,然后在本地负载机的Controller的Load Generators里Add另一台负载机的Name(可以填写IP地址,比如192.168.6.173),然后点击connect按钮,查看status是否变为Ready状态,最后就可以在不同的虚拟用户组指定不同的负载机来帮助我们完成性能测试了。
– 具体操作步骤可以参考网上的资料
场景运行完成以后, 不代表我们的性能测试结束, 相反,这才是性能测试的开始,因为接下来,我们需要对运行数据进行分析,找出性能瓶颈,然后调优或者提交BUG。
- Analysis
– 在介绍Analysis的使用之前, 下面将针对一些常用的监控资源进行说明。
- 我大致将监控分为3类
- ①负载机的系统监控与被测系统监控(一般包括CPU使用率、内存、磁盘IO等)
- ②服务器处理能力的指标监控(一般包括吞吐量、每秒事物数、各个事物的响应时间、每秒单击数等)
- ③网络监控(根据经验,就是查看对比前后流量,ping服务器等)
– CPU利用率(% Processor Time):指处理器执行非闲置线程时间的百分比。这个计数器设计成用来作为处理器活动的主要指示器。它通过在每个时间间隔中衡量处理器用于执行闲置处理线程的时间,并且用100%减去该值得出。可将其视为范例间隔用于做有用工作的百分比。根据应用系统情况,在80%±5%范围内波动为宜。过低,则服务器CPU利用率不高;过高,则CPU可能成为系统的处理瓶颈。
– 可用物理内存( Available MBytes ):当这个数值变小时,Windows开始频繁地调用磁盘页面文件。如果这个数值很小,例如小于5 MB,系统会将大部分时间消耗在操作页面文件上。一般要保留10%的可用内存。最低不能<4M,此值过小可能是内存不足或内存泄漏。
– 磁盘IO(% Disk Time):指所选磁盘驱动器忙于为读或写入请求提供服务所用的时间的百分比。正常值<10,此值过大表示耗费太多时间来访问磁盘,可考虑增加内存、更换更快的硬盘、优化读写数据的算法。若数值持续超过80 (此时处理器及网络连接并没有饱和),则可能是内存泄漏。
– 事务平均响应时间:( Average Transaciton Response Time ):随着测试时间的变化,系统处理事务的速度开始逐渐变慢,这说明应用系统随着投产时间的变化,整体性能将会有下降的趋势。好<2s、良好2~5s、差6~10s
– 吞吐量( Throughput ):可以依据服务器的吞吐量来评估虚拟用户产生的负载量,以及看出服务器在流量方面的处理能力以及是否存在瓶颈。
– 每秒点击次数( Hits per Second ):通过对查看“每秒点击次数”,可以判断系统是否稳定。系统点击率下降通常表明服务器的响应速度在变慢,需进一步分析,发现系统瓶颈所在。
虚拟用户数(Running Vusers): 这个主要用于与其他监控数据结合来分析问题的。
- Analysis
- 执行结果分析过程
– 场景执行完成以后,需要对运行过程中收集的数据信息进行分析,从而来了解系统性能表现能力,确定系统性能瓶颈。在Loadrunner Controller中,通过单击【Results】>【Analyze Results】菜单项,启动Loadrunner Analysis应用,如果左侧的Graphs中没有出现你想要的图,就点击工具条按钮“Add New Graph…”,把关心的图加入进来,如下图:
- Analysis
- 合并图的应用
– 有时候看单一的图,很难看出图与图之间的关联,所以这时候,我们可以采用合并图来进行有机的结合。合并图的方法就是先选择一张合并图,然后在图的空白处单击鼠标右键选择【Merge Graphs…】选项,接着选择被合并图(可以选择合并图类型、可以更改标题),如下图:
- Analysis
- 合并图的应用
合并图共提供了3种方式:叠加(Overlay)、平铺(Tile)和关联(Correlate),下面针对这3种合并方式做一下简单的介绍。
(1)叠加方式:使得两个图使用相同横轴的图的排列方式。合并图的左侧纵轴显示当前图的值,右侧纵轴显示被合并图的值。
(2)平铺方式:两个图一个位于另一个之上,合并图在下方,而被合并图在上方,使得两个图共同使用一个横轴,两个图分别使用搁置的纵轴
(3)关联方式:使得合并图的纵轴将变成合并图的横轴,被合并图的纵轴将变成合并图的纵轴。