8.性能测试流程及策略
一、准备工作
1.系统基础功能验证
性能测试在什么阶段适合实施,切入点很重要,一般而言,只有在系统基础功能测试验证完成,系统区域稳定的情况下,才会进行性能测试,否则性能测试是无意义的。
2、测试团队组建
根据项目的具体情况,组建一个几个人的性能测试团队,其中DBA(数据库管理员)是必不可少的,然后需要一至几名系统开发人员(对应前端、后台等),还有性能测试设计、分析,脚本开发和执行人员。
在正式开始工作之前,因该对脚本开发和执行人员进行一些培训,或者因该由具有相关经验的人员担当。
3.工具选择
综合系统设计、工具成本、测试团队的技能来考虑,选择合适的测试工具,最起码满足以下几点:
①支持对web(这里以web系统为例)系统的性能测试,支持http和https协议;
②工具运行在Windows平台上;
③支持对webserver、前端、数据库的性能计数器进行监控;
4.预先的场景分析
为了对系统性能建立直观的认识和分析,应对系统重要和常用业务场景模块进行分析,针对性的进行分析,以对接下来的测试计划设计进行准备
二、测试计划
测试计划极端最重要的是分析用户场景,确定系统性能目标。
1.性能测试领域分析
根据对项目背景,业务的了解,确定本次性能测试要解决的问题点;是测试系统能否满足实际运行时的需要,还是目前的系统在哪些方面制约系统性能的表现,或者,哪些系统因素导致
系统无法跟上业务发展?确定测试领域,然后具体问题具体分析。
2、用户场景剖析和业务建模
根据对系统业务、用户活跃时间、访问频率、场景交互等各方面的分析,整理一个业务场景表,当然其中最好对用户操作场景、步骤进行详细的描述,为测试脚本开发提供依据。
3、确定性能目标
前面已经确定了本次性能测试的应用领域,接下来就是针对具体的领域关注点,确定性能目标(指标);其中需要和其他业务部门进行沟通协商,以及结合当前系统的响应时间等数据,确定
最终我们需要达到的响应时间和系统资源使用率等目标;比如:
①登录请求到登录成功的页面响应时间不能超过2秒;
②报表审核提交的页面响应时间不能超过5秒;
③文件的上传、下载页面响应时间不超过8秒;
④服务器的CPU平均使用率小于70%,内存使用率小于75%;
⑤各个业务系统的响应时间和服务器资源使用情况在不同测试环境下,各指标随负载变化的情况等;
4、制定测试计划的实施时间
预设本次性能测试各子模块的起止时间,产出,参与人员等等。
三、测试脚本设计与开发
性能测试中,测试脚本设计与开发占据了很大的时间比重。
1、测试环境设计
本次性能测试的目标是需要验证系统在实际运行环境中的性能外,还需要考虑到不同的硬件配置是否会是制约系统性能的重要因素!因此在测试环境中,需要部署多个不同的测试环境,
在不同的硬件配置上检查应用系统的性能,并对不同配置下系统的测试结果进行分析,得出最优结果(最适合当前系统的配置)。
这里所说的配置大概是如下几类:
①数据库服务器
②应用服务器
③负载模拟器
④软件运行环境,平台
测试环境测试数据,可以根据系统的运行预期来确定,比如需要测试的业务场景,数据多久执行一次备份转移,该业务场景涉及哪些表,每次操作数据怎样写入,写入几条,需要多少的
测试数据来使得测试环境的数据保持一致性等等。
可以在首次测试数据生成时,将其导出到本地保存,在每次测试开始前导入数据,保持一致性。
2、测试场景设计
通过和业务部门沟通以及以往用户操作习惯,确定用户操作习惯模式,以及不同的场景用户数量,操作次数,确定测试指标,以及性能监控等。
3、测试用例设计
确认测试场景后,在系统已有的操作描述上,进一步完善为可映射为脚本的测试用例描述,用例大概内容如下:
用例编号:查询表单_xxx_x1(命名以业务操作场景为主,简洁易懂即可)
用例条件:用户已登录、具有对应权限等。。。
操作步骤:
①进入对应页面
②查询相关数据
③勾选导出数据
④修改上传数据
PS:这里的操作步骤只是个例子,具体以系统业务场景描述;
4、脚本和辅助工具的开发及使用
按照用例描述,可利用工具进行录制,然后在录制的脚本中进行修改;比如参数化、关联、检查点等等,最后的结果使得测试脚本可用,能达到测试要求即可;
PS:个人而言,建议尽量自己写脚本来实现业务操作场景,这样对个人技能提升较大;一句话:能写就绝不录制!!!
四、测试执行与管理
在这个阶段,只需要按照之前已经设计好的业务场景、环境和测试用例脚本,部署环境,执行测试并记录结果即可。
1、建立测试环境
按照之前已经设计好的测试环境,部署对应的环境,由运维或开发人员进行部署,检查,并仔细调整,同时保持测试环境的干净和稳定,不受外来因素影响。
2、执行测试脚本
这一点比较简单,在已部署好的测试环境中,按照业务场景和编号,按顺序执行我们已经设计好的测试脚本。
3、测试结果记录
根据测试采用的工具不同,结果的记录也有不同的形式;现在大多的性能测试工具都提供比较完整的界面图形化的测试结果,当然,对于服务器的资源使用等情况,可以利用一些计数器或
第三方监控工具来对其进行记录,执行完测试后,对结果进行整理分析。
五、测试分析
1、测试环境的系统性能分析
根据我们之前记录得到的测试结果(图表、曲线等),经过计算,与预定的性能指标进行对比,确定是否达到了我们需要的结果;如未达到,查看具体的瓶颈点,然后根据瓶颈点的具体数据,
进行具体情况具体分析(影响性能的因素很多,这一点,可以根据经验和数据表现来判断分析)。
2、硬件设备对系统性能表现的影响分析
由于之前设计了几个不同的测试环境,故可以根据不同测试环境的硬件资源使用状况图进行分析,确定瓶颈是再数据库服务器、应用服务器抑或其他方面,然后针对性的进行优化等操作。
3、其他影响因素分析
影响系统性能的因素很多,可以从用户能感受到的场景分析,哪里比较慢,哪里速度尚可,这里可以根据2\5\8原则对其进行分析;
至于其他诸如网络带宽、操作动作、存储池、线程实现、服务器处理机制等一系列的影响因素,具体问题具体分析,这里就不一一表述了。
4、测试中发现的问题
在性能测试执行过程中,可能会发现某些功能上的不足或存在的缺陷,以及需要优化的地方,这也是执行多次测试的优点。
六、性能测试思维导图
测试流程图:
七、性能测试策略
1、项目具体需求及业务场景:关注真实用户会是怎样的一个业务场景,确定用户的用户习惯。
2、指标:响应时间在多少以内,并发数多少,tps多少,总tps多少,稳定性交易总量多少,事务成功率,交易波动范围,稳定运行时长,资源利用率,测哪些交易,哪些接口,测试哪些场景。
3、环境:生产环境服务器数量,测试环境服务器数量,按照资源配比得出测试指标。
4、协议:系统用什么协议进行通讯。
5、压力机数量:如果并发用户数太多,需要把压力发到不同的压力机,不然可能会存在压力机瓶颈问题,导致tps和响应时间抖动。
6、交易占比:分析线上日志得出tps占比。
7、系统架构:请求流经过哪些环节,压测时监控这些环节。
一、测试过程中cpu过高
1、用vmstat实时监控cpu使用情况。很小的压力AP cpu却到了80%多,指标是不能超过60%。
2、分析是use cpu过高还是sys cpu过高,常见的是use cpu使用过高。
3、如果是sys cpu使用过高,先把消耗cpu最多的进程找出来(top命令),再找到该线程下消耗cpu过高的是哪几个线程,再把该线程转换成16进制,再用jstack命令来dump线程栈,看这个线程栈在调用什么东西导致use cpu过高。
二、内存溢出(堆溢出、栈溢出、持久代溢出)
1、堆内存溢出
1)稳定性压测一段时间后,LR报错,日志报java.lang.OutOfMemoryError.Java heap space。
2)用jmap -histo pid命令dump堆内存使用情况,查看堆内存排名前20个对象,看是否有自己应用程序的方法,从最高的查起,如果有则检查该方法是什么原因造成堆内存溢出。
3)如果前20里没有自己的方法,则用jmap -dump来dump堆内存,在用MAT分析dump下来的堆内存,分析导出内存溢出的方法。
4)如果应用程序的方法没有问题,则需要修改JVM参数,修改xms,xmx,调整堆内存参数,一般是增加堆内存。
2、栈内存溢出
1)稳定性压测一段时间后,LR报错,日志报Java.Lang.StackOverflowError。
2)修改jvm参数,将xss参数改大,增加栈内存。
3)栈溢出一定是做批量操作引起的,减少批处理数据量。
3、持久代溢出
1)稳定性压测一定时间后,日志报Java.Lang.OutOfMenoryError.PermGen Space。
2)这种原因是由于类、方法描述、字段描述、常量池、访问修饰符等一些静态变量太多,将持久代占满导致持久代溢出。
3)修改jvm配置,将XX:MaxPermSize=256参数调大。尽量减少静态变量。
三、线程死锁
1、容量测试压测一段时间后,LR报连接超时。
2、造成这种现象的原因很多,比如带宽不够,中间件线程池不够用,数据库连接池不够,连接数占满等都会造成连接不上而报超时错误。
3、jstack命令dump线程栈,搜索线程栈里有没有block,如果有的话就是线程死锁,找到死锁的线程,分析对应的代码。
四、数据库死锁
1、容量测试压测一段时间后,LR报连接超时。
2、造成这种现象的原因很多,比如带宽不够,中间件线程池不够用,数据库连接池不够,连接数占满等都会造成连接不上而报超时错误。
3、数据库日志中搜索block,能搜到block的话就是存在数据库死锁,找到日志,查看对应的sql,优化造成死锁的sql。
五、数据库连接池不释放
1、容量测试压测一段时间后,LR报连接超时。
2、造成这种现象的原因很多,比如带宽不够,中间件线程池不够用,数据库连接池不够,连接数占满等都会造成连接不上而报超时错误。
3、去数据库查看应用程序到数据库的连接有多少个( show full processlist),假如应用程序里面配置的数据库连接为30,在数据库查看应用程序到数据库的连接也是30,则表示连接池占满了。将配置改成90试试,去数据库看如果连接到了90,则可以确定是数据库连接池不释放导致的。查看代码,数据库连接部分是不是有创建连接但是没有关闭连接的情况。基本就是这种情况导致的,修改代码即可。
六、TPS上不去
1、压力大的时候tps频繁抖动,导致总tps上不去。查看是否有fullgc(tail -f gc_mSrv1.log | grep full)。
2、pacing设置太小也会导致tps上不去,对抖动大的交易多增加点用户即可。
3、tps抖动,单压抖动大的交易,发现很平稳,这时怀疑是不是压力太大导致,所以发容量的时候把压力最大的那只交易分到其他压力机,然后发现tps不抖动了。注意:多台压力机只影响tps抖动,不会影响服务器的cpu。
4、看响应时间有没有超时,看用户数够不够。
七、服务器压力不均衡(相差1%-2%是正常的)
1、跑最优容量的时候,四台AP只有一台cpu超过60%,其他三台都在60%以下。
2、查看服务器是否有定时任务。
3、查看是否存在压力机瓶颈。
4、是否存在带宽瓶颈(局域网不存在此问题)。
5、查看部署的版本,配置是否一样。
6、可能别人也在用这些AP,因为同一台物理机上有很多虚拟机,因为别人先用,资源被别人先占了。
八、fullgc时间太长
1、跑容量和稳定性的时候,出现LR报请求超时错误,查看后台日志是fullgc了,看LR几点报的错和日志里fullgc的时间是否对应,fullgc会暂停整个应用程序,导致LR前端没响应,所以报错,这时可以减少old代内存,从而减少fullgc时间,减少fullgc时间LR就不会报错,让用户几乎感觉不到应用程序暂停。
2、四台AP轮流着full gc(部分server fullgc,其他server也会fullgc),这时可以制定策略让不同的server不同时fullgc,或者等夜间交易量少时写定时任务重启服务。
9、分析
1.具体性能的分析流程
首先看关键指标是否满足需求,如果不满足,需要确定是哪个地方有问题,一般情况下,服务器端问题可能性比较大,也有可能是客户端问题(这种可能性非常小)。
如果是服务器端的问题,需要定位的问题有硬件相关指标,例如CPU,Memory,Disk I/O,Network I/O,如果是某个硬件指标有问题,需要深入的进行分析。如果中间件相关指标没问题,需要查看数据库相关指标,例如:慢查SQL,命中率,锁,参数设置。
如果以上指标都正常,应用程序的算法、缓冲、缓存、同步或异步可能有问题,需要具体深入的分析。
2.如果让你去优化前端页面,你的优化流程是?
遇到问题,第一步是确定问题,先要确定是前端的问题还是后端的问题。
如果是前端的问题,那就要确定在哪些地方出了问题,按照前端的各种检测方法来检查。
如果是后端的问题,就从系统、中间件、数据库、网络等方面入手。
如何确定问题呢?
比如用Firefox的firebug调试,看一次请求在各部分分别花了多少时间,哪些请求耗时最长。
如果请求的是静态资源,时间很长,就需要考虑部署CDN啥的;
如果请求的不是静态资源而是服务器数据,时间长速度慢,那就分两种情况进行考虑:第一是后端的问题,第二是前端渲染问题。
如果返回数据很快,但界面数据没出来,就要考虑是前端js程序问题还是图片等资源太大的问题等等。
测试策略在结构上可以包括以下一些要点:
(1)测试级别:常见的测试级别有单元测试,集成测试和系统测试。大部分的测试组织里面,单元测试由开发负责,而集成测试和系统测试由测试部门或者质量保证部门负责。
(2)角色与职责:需要在测试策略里面明确定义各个角色,以及该角色的职责。比如项目经理,测试组长,测试工程师…
(3)环境需求:这一点非常重要,它将描述测试时需要的系统环境,包括软硬件以及网络环境等等。在澄清环境需求的时候,测试组织可以识别出资源方面的风险。
(4)风险分析:影响测试过程的风险都应该尽早被识别出来,而且必须有相应的解决办法以便消除或者减轻这些风险。
(5)测试进度:测试进度将会评估完成测试所需要的时间。在设定进度的时候,首先需要明确测试范围,然后根据测试资源的多少来制定能被各方面认可的测试进度计划。做一个非常准确的进度计划是困难的事情,因为测试过程中充满了各种不确定性,所以一般计划者需要考虑增加一定的buffer。当然,制定进度计划的时候可以参考已有的项目的数据。如果是一个全新的软件项目,专家认为将初始计划的时间翻倍比较靠谱!
(6)回归测试方法:回归测试用来保证之前fix bug的代码不会影响软件的其他部分,这样需要我们选择已经执行过的测试用例重新运行。测试人员需要找到一个方法来确定哪些测试用例应该在回归测试中运行,用例不能太多,因为资源有限,用例也不能太少,否则会达不到必须的测试强度。不过,如果测试部门对待测系统以及软件架构非常了解的话,就比较容易找到合适的回归测试集合。
(7)测试范围:这个没啥好说的,就是你要测试的内容,可能是某些模块,可能是某些指标,比如功能,性能,易用性…
者需要考虑增加一定的buffer。当然,制定进度计划的时候可以参考已有的项目的数据。如果是一个全新的软件项目,专家认为将初始计划的时间翻倍比较靠谱!
(6)回归测试方法:回归测试用来保证之前fix bug的代码不会影响软件的其他部分,这样需要我们选择已经执行过的测试用例重新运行。测试人员需要找到一个方法来确定哪些测试用例应该在回归测试中运行,用例不能太多,因为资源有限,用例也不能太少,否则会达不到必须的测试强度。不过,如果测试部门对待测系统以及软件架构非常了解的话,就比较容易找到合适的回归测试集合。
(7)测试范围:这个没啥好说的,就是你要测试的内容,可能是某些模块,可能是某些指标,比如功能,性能,易用性…
(8)测试优先级:测试范围内的东西不会都是一样重要的,加上测试资源各种有限,所以为测试排定优先级是十分的必要。