如何进行有效的性能测试
下方查看历史精选文章
大数据测试过程、策略及挑战
在性能测试系列前面几篇文章中我们比较详细的介绍了相关的知识
所有性能相关的文章,均会同步发布至下面的公众号,大家可以关注,以免错过
而本文讲系统的介绍,如何进行有效性能测试的基础,将从以下几个方面来介绍:
应用环境的准备工作
如何冻结代码变更
设计性能测试环境
设计合理的性能测试目标
梳理关键业务测试场景和开发测试脚本
如何准备/管理性能测试数据
如何精确的设计性能测试场景
确定关键性能指标
下面对上述几个方面进行一一说明。
一、应用测试环境的准备工作
在开始性能测试之前,我们必需首先确保应用测试环境的部署正常、功能基本稳定,以免在性能测试过程中因个别bug的修复,而导致性能测试实施阻塞。毕竟如果系统存在功能上的明显问题,那么在这样的版本之上开始性能测试是没什么意义的。
通常情况下,现在的应用都会使用到数据库,如果数据库相关的配置或存在一些慢sql或效率不高的存储过程都会给性能带来巨大的负面影响,在开启性能测试实施之前,应该有针对性对数据库相关配置、慢sql、低效的存储过程进行一一清理。
对于一个复杂的系统,网络带宽也是我们必需准备好的基础实施,毕竟相当多的性能测试会在生产环境进行,所以对于基础网络带宽也应该有一个基础的预判和准备。
性能测试实施是一个繁琐和漫长的过程,在规划性能测试时,应该尽可能的预留出足够的时间。
对于目标压测系统相关的配置、基础资源准备得七七八八的情况下,压测机方面的资源我们也应当做好相应的资源准备,是单机就能满足压力的需求还是需要进行分布式压测的准备?都是需要考虑准备的。
梳理性能测试场景和开发、调试压测脚本是性能测试至关重要的步骤,在这个过程中,我们会逐步建立和验证性能测试场景,以达成本次压测的目标。
还有个最为关键的准备工作:梳理、准备和清理测试数据。准备测试数据是成功实施性能测试的必备条件,而且数据准备也是一项精细的活,需要一定的时间和精力,包括测试数据后续的清理方案也是要考虑在内的。
最后一个准备工作就是:应对和解决突发问题的时间的预留,我们在实施性能测试时,不可避免的会有各类突发问题的出现,例如环境、配置、代码变更等等因素引起的突发事件,我们也需要预留一定的时间来应对这类的问题。
二、代码冻结变更机制
通常情况下,我们都会在一个稳定的代码版本之上做性能测试实施,但在性能测试中发现的问题有可能是需要进行代码变更的,这也是允许的,但一般是基于当下在测的稳定的代码版本进行修复变更迭代,绝对不允许开发随意迭代变更代码。而且有了变更应当、也必须通知到相关人员。
否则随意变更代码,极端的可能导致性能测试脚本得重新开发、调试。严格的管控代码变更和合理的变更通知机制是必不可少的。
三、设计性能测试环境
理论上,最理想的性能测试环境应对和生产环境一致,而大部分企业是做不到这个的,所以我们要有以下处理方案。
在配置上,我们尽量做到性能测试环境与生产环境的一致。
在基础中间件方面,也需要做到版本一致、配置一致。
在网络设施方面,尽量让测试环境和生产环境的网络基础设施共享相同的网络设施(这个大体可以做到,因为我们通常都是将服务部署在云上)。
在数据库版本、容量、配置方面也是尽可能的保持两个环境的一致,否则由于数据库版本、容量、配置的差异带来的影响会直接导致性能测试结果不准确。
总结一下,在一些绕不开的限制条件下,我们要尽可能的保持性能测试环境和生产环境的一致。
如果准备充分、条件允许,我们也是可能考虑,直接在生产环境进行性能测试实施,这样所得到的结果是最为精确的。
四、设计合理的性能测试目标
在进行性能测试前,首先就要设定合理的性能测试目标或是期望,而不是为了做性能测试而测试。
在设定性能目标时,最关键的是与各方干系人达成一致的认可,这些干系人包括用户、管理层、研发、测试、运维等等。
否则我们在性能测试实施的结果可能会达成相应的结果。
也只有目标得到相关干系人的认可,我们在最终调度开发、运维、测试去实施时,才能更好的协调好相关资源、过程中攻克相关难点,满足最终需求的去做好相应的性能测试实施成功。
一些关键指标在设定目标时,通常需要关注的有:
可用性
并发
吞吐率
响应时间
网络利用率
服务器利用率
大家可以参考之前的文章 从终端用户感受来体验性能指标度量 来了解关键指标上的一些说明。
五、梳理关键业务测试场景和开发测试脚本
测试场景是性能测试的基础,我们必需确保梳理出来满足性能测试目标的业务场景。一个典型的业务场景是:登录 - 业务操作(查询、新增、编辑、删除动作) - 退出系统
要注意的是,不要把性能测试场景与功能测试混淆起来,性能测试的目标不是确保服务的功能正确(功能测试的准确应该是在性能测试之前验证过了),而是要针对应用制定符合真实的负载来使服务工作在压力之下进而从性能的角度来观察服务的表现。
性能测试的目的在于暴露由于并发、容量不足或配置问题等导致的瓶颈。
在梳理测试场景时有以下一些注意点:
确保场景无二义性,这样才能确保对应的测试脚本没有异议
确保所有的输入数据需求和期望返回结果
区分好不同的用户角色,例如有管理角色、有查询角色、有编辑角色、有删除角色等等,也要确定其大体比例,例如查询角色的用户占更大比例,当然这个不能照搬,得根据实际的业务场景来定
确定压测时的网络环境,局域网还是广域网还是混合网络环境
梳理出来的测试场景可回放验证
上面这些是一些大体的思路,大家要进一步根据对业务、环境的熟悉度来进一步挖掘、梳理。
六、如何准备/管理性能测试数据
准备高质量的测试数据是保证性能测试有效进行的基础,可以这么说:性能测试的成败取决于测试数据的数量和质量。
先不管业务的情况下,我们可以对数据大体分为三个类型:
输入数据
基础数据
会话数据
下面我们对上述三类数据进行分解说明。
输入数据
一般包括用户信息、查询条件、关联文件。
用户信息这个比较好理解,我们现在几乎所有的业务系统都基于用户会话为中心构建的,用户信息包括了登录id、密码,有的会有验证码。
一般情况下,我们在做性能测试时,会提前去专门新增一批专用的用户账户。
查询条件,几乎在所有的性能测试过程中,都会有各种查询业务场景,为了使我们的场景尽可能的逼近真实情况,我们需要准备好多样化的查询。
关联文件,在很多业务类型中,会有各种附件的上传、下载功能,这些附件可能会涉及pdf、word、excle、png等各种格式,我们需要根据实际情况来准备。
基础数据
如果我们不是在生产环境进行线上的性能测试,那么在相应的性能测试环境里,需要提前导入能够模拟线上环境的基础数据,例如用户信息、业务订单信息等等有效数据,而且也要确保这些基础数据有一定的量。而不是随意一点的量意思一下。
例如你线上数据库有1TB的数据量,你在测试环境只有100M的数据量,那这个玩笑就有点大了,测试出来的结果可能会有很大的偏差。
所以在创建和维护性能测试数据库时,也是一个很大的挑战,具体体现在如下几个方面:
确保性能测试数据库大小尽可能的接近真实。
在每次进行性能测试前,需要对数据库进行备份,最好每次执行前,做一次数据回滚。
数据量较大的情况下,数据回滚所需要的时间,需要提前演练,做好预估。
会话数据
在性能测试执行过程中,必然会涉及一些由服务端返回的数据,需要我们进行处理,并应用于性能测试过程中。一个典型的会话数据:例如token。所以对于这类数据我们一定要做好相应的处理,以免导致整个性能测试过程上的一些逻辑上的问题。
最后要注意一点的是,现在很多业务系统都会出一些关键数据做一些脱敏处理,这些可能会影响到我们性能测试过程中的一些脚本开发工作,这些就需要跟开发人员做好相关的沟通协作。同一样的,对于一些敏感数据,例如用户名/密码、身份证、银行卡这类的数据,要做好规避,以免泄露出去,造成不必要的一些问题出现。
七、如何精确的设计性能测试场景
为了精确的设计好性能测试场景,我们必需将上文涉及的知识进行综合应用。通过测试场景来精确的模拟性能测试目标中定义的相关指标。
下面我们看看设计好性能测试场景,必需理解的几种性能测试类型。
基准测试
基准测试,也是一种准备性、参考性测试,通过基准测试,我们可以验证我们的性能测试脚本的可行性。通常情况下,基准测试基于单位用户来执行测试场景(注:单位用户,可以是一个用户,也可以是10个,具体根据需要来定义),可以执行一段时间,或一定循环次数。
通过基准测试,我们要达成以下几个小目标:
验证我们的性能测试脚本的可行性
获取基准的指标监控信息
根据基准测试所采集的监控数据,来评估后续的测试趋势
负载测试
负载测试是最典型的性能测试类型,在负载测试过程中会施加足够的负载来达成预期的并发目标。
通常在负载达到预期目标后,一般不会继续增加负载,而是会保持负载不变的情况下,去验证系统的可行性、并发数、吞吐率和响应时间等技术指标。
压力测试
压力测试的目标与上述两种测试会不大一样。我们会利用压力测试去尝试探索系统的某些指标的极限能力。因此在压力测试过程中,会持续的一直增加负载,直到系统的部分功能不能正常工作。
稳定性测试
稳定性测试是为了发现那些经过长时间运行才会暴露的问题。典型的例如缓慢的内存泄漏,持续长时间下偶发的线程锁等等。为了配合发现这类的问题,我们需要去构建持续的基础监控系统,来对相关指标进行持续性的监控,以便于我们分析、挖掘问题所在。
当然了,在你会在其他书籍或博客上看到还有其他各种性能测试类型,例如容量测试、冒烟测试、隔离测试等等,这里就不一一说明了,我笔者的实践中,基准、负载、压力和稳定性测试是最常用的类型。
为了做好我们的性能测试场景,我们需要充分考虑测试数据的量对场景的影响,通常有量的方式:小数据量模式、中等数据量模式、大数据模式。
这里的数据量,主要是指我们基础数据量,打个简单的比方,你的数据库里有100条订单记录和有1千万条订单记录,对性能测试的结果的影响会有质的区别。所以我们在构建性能测试模型时,要充分考虑各种情况。
下面我们看看性能测试过中,施压的一般采用的两种方式。
大爆炸式施压
递增方式施压
大爆炸式
这种模式的意思是,所有虚拟用户同时执行,用于模拟单位时间内大压力的业务模型,例如我们像秒杀,业务活动期间,会有大量的用户业务行为。
递增式
这种模式,一般会在开始时启动一部分虚拟用户执行,然后按照固定的单位时间间隔逐步增加虚拟用户,直至达到某个特定的数量。在我们评估一个服务能支撑多少并发用户时,通常会采用这种模式。
这种方式一般又会分为下面两种方式:
1. 分段递增方式,即我们会测试某个或某些指标,但在执行过程中的某些时刻我们会保持一定的虚拟用户数。例如我们的并发目标是2000,但在这个过程我们需要观察500、1000、1500并发情况的相关指标。这时我们会根据这些阶段目标,在施压的过程中,当并发用户达到了指定的值,就会暂停继续新增并发数,直到我们观察、采集了完成了相关指标的数据后,才会继续新增并发数。当然这个也可以通过独立的多个测试来达成效果。
2. 分段递增然后递减方式,这个我们会用于模拟业务系统经历一定的业务峰值后,业务下降时的业务情况。但不是所有工具都支持这种方式的。
不管是哪种方式,我们应该根据业务特征来设计多种模式,以达到深入探索、挖掘、评估系统的性能情况。
八、确定关键性能指标
性能测试过程中必须明确需要监控的服务器和网络关键性能指标。因为我们在进行性能测试过程中的问题的分析、溯源,基本都是依赖这些基础、关键的监控指标。
在理想情况下,这些监控应该是被整合进性能测试方案里的,但在实际操作中,受限于工具的能力,大部分情况采取的是性能测试和监控分离的方式,而不是监控集成进工具里。
下面我们看看要监控哪些关键的性能指标和一般用到的监控工具,这里大家可以参考之前的文章:
服务器指标监控,通常通过安装监控软件来采集一些特定的性能数据或性能计数器,我们通常比较熟悉的有Perfmon(这是windows自带的工具),这个工具有数以百计的性能计数器。很适合windows平台的监控。
在unix/linux下,则有很多的命令可用,例如top、monitor、vmstat、iostat等等。
当然更好的方式,笔者推荐你采用zabbix这类通用的服务器监控系统,免费、开源好用。
下面是笔者整理出来,大家在构建自己的监控体系时,需要去关注的关键指标,这些指标覆盖关键的监控指标:例如cpu、io、内存、网络错误等
- CPU使用率%
- 处理器队列长度
- 每秒上下文切换次数
- 可用内存
- 内存:每秒页面失效次数
- 内存:每秒换成失效次数
- 内存:每秒物理页读取次数
- 虚拟内存页使用率%
- 基于上一次计数的前十进程
- 磁盘空间可用率%
- 物理磁盘:平均磁盘队列长度
- 物理磁盘:磁盘时间百分比%
- 网卡:接收包错误率
- 网卡:发送包错误率
web和应用程序,这块的监控主要关注web或应用程序服务器层的,例如tomcat、apache等这类的web服务器的监控。
数据库服务器,我们最熟悉的数据库有Oracle、Mysql、sql server等等,我们也是需要去进行监控,主要监控:
- 全面了解数据库的监控状况和性能。
- 根据慢SQL、排查响应时间延误、故障、页面错误等。
在网络指标方面,我们主要关注网路包的传输时间、数据流量以及大流量时可能导致的网络错误。在这方面,我们通常监控几个少数关键指标就好了,一般包括以下几项:
- 网络错误,对于性能来讲,任何网络错误都是值得我们去关注的,因为网络错误可以反映网络设备的无聊问题或是流量过载问题
- 网络延迟
- 网络带宽消耗
在本文中,我们一起了解了如何有效开展性能测试的关键前置条件,不管你之前在性能测试方面是否有足够的了解,强烈推荐你把本文收藏,后续反复查阅。