性能测试,七个主题,完善性能测试知识体系
大量用户并发访问时的负载,以及可能的更大负载情况下的系统健康状态、并发处理能力、当前部署的系统容量、可能的系统瓶颈、系统配置层面的调优、数据库的调优,以及长时间运行稳定性和可扩展性。
系统运维人员必须在最大并发用户数和系统响应时间之间进行权衡取舍。
目前,有些系统为了能够承载更多的并发用户,往往会牺牲等待时间而引入预期的等待机制。比如,火车票购票网站,就在处理极大并发用户时采用了排队机制,以尽可能提高系统容量,但却增加了用户实际感受到的响应时间。
在软件设计开发人员眼中,软件性能通常会包含算法设计、架构设计、性能最佳实践、数据库相关、软件性能的可测试性这五大方面。
一个优秀的性能测试工程师,一般需要具有以下技能:
并发用户数、响应时间,以及系统吞吐量。
并发用户数,是性能需求与测试最常用,也是最重要的指标之一。它包含了业务层面和后端服务器层面的两层含义。
为了让你更好地理解这两层含义之间的区别,我们先一起来看一个实例:一个已经投入运行的ERP系统,该系统所在企业共有5000名员工并都拥有账号,也就是说这个系统有5000个潜在用户。
根据系统日志分析得知,该系统最大在线用户数是2500人,那么从宏观角度来看,2500就是这个系统的最大并发用户数。但是,2500这个数据仅仅是说在最高峰时段有2500个用户登录了系统,而服务器所承受的压力取决于登录用户的行为,所以它并不能准确表现服务器此时此刻正在承受的压力。
假设在某一时间点上,这2500个用户中,30%用户处于页面浏览状态(对服务器没有发起请求),20%用户在填写订单(也没有对服务器发起请求),5%用户在递交订单,15%用户在查询订单,而另外的30%用户没有进行任何操作。那么此时,这2500个“并发用户”中真正对服务器产生压力的只有500个用户((5%+15%)*2500=500)。
在这个例子中,5000是最大的“系统潜在用户数”,2500是最大的“业务并发用户数”,500则是某个时间点上的“实际并发用户数”。而此时这500个用户同时执行业务操作所实际触发的服务器端的所有调用,叫作“服务器并发请求数”。
从这个例子可以看出,在系统运行期间的某个时间点上,有一个指标叫作“同时向服务器发送请求的数量”,这个“同时向服务器发送请求的数量”就是服务器层面的并发用户数,这个指标同时取决于业务并发用户数和用户行为模式,而且用户行为模式占的比重较大。
因此,分析得到准确的用户行为模式,是性能测试中的关键一环。但,获得精准的用户行为模式,是除了获取性能需求外,最困难的工作。
目前,获取用户行为模式的方法,主要分为两种:
一般来讲,响应时间反映了完成某个操作所需要的时间,其标准定义是“应用系统从请求发出开始,到客户端接收到最后一个字节数据所消耗的时间”,是用户视角软件性能的主要体现。
系统响应时间,又可以进一步划分为Web服务器时间、应用服务器时间、数据库时间,以及各服务器间通信的网络时间。
软件的性能测试一般更关注服务器端。但是,服务器端响应时间的概念非常清晰、直接,就是指从发出请求起到处理完成的时间
响应时间应该包含两层含义:技术层面的标准定义和基于用户主观感受时间的定义。而在性能测试过程中,我们应该使用哪个层面的含义将取决于性能测试的类型。
对于软件服务器端的性能测试肯定要采用标准定义,而对于前端性能评估,则应该采用用户主观感受时间的定义。
系统吞吐量,是最能直接体现软件系统负载承受能力的指标。所有对吞吐量的讨论都必须以“单位时间”作为基本前提。
把“Throughput”翻译成吞吐率更贴切,因为我们可以这样理解:吞吐率=吞吐量/单位时间。但既然国内很多资料已经翻译为了“吞吐量”,所以通常情况下我们不会刻意去区分吞吐量和吞吐率,统称为吞吐量。
对性能测试而言,通常用“Requests/Second”“Pages/Second”“Bytes/Second”来衡量吞吐量。当然,从业务的角度来讲,吞吐量也可以用单位时间的业务处理数量来衡量。
这里需要特别注意的是:虽说吞吐量可以反映服务器承受负载的情况,但在不同并发用户数的场景下,即使系统具有相近的吞吐量,但是得到的系统性能瓶颈也会相差甚远。
比如,某个测试场景中采用100个并发用户,每个用户每隔1秒发出一个Request,另外一个测试场景采用1000个并发用户,每个用户每隔10秒发出一个Request。显然这两个场景具有相同的吞吐量, 都是100 Requests/second,但是两种场景下的系统性能拐点肯定不同。因为,两个场景所占用的资源是不同的。
这就要求性能测试场景的指标,必然不是单个,需要根据实际情况组合并发用户数、响应时间这两个指标。
把常用的性能测试方法分为七大类:后端性能测试(Back-end Performance Test)、前端性能测试(Front-end Performance Test)、代码级性能测试(Code-level Performance Test)、压力测试(Load/Stress Test)、配置测试(Configuration Test)、并发测试(Concurrence Test),以及可靠性测试(Reliability Test)
是通过性能测试工具模拟大量的并发用户请求,然后获取系统性能的各项指标,并且验证各项指标是否符合预期的性能需求的测试手段。
性能指标,除了包括并发用户数、响应时间和系统吞吐量外,还应该包括各类资源的使用率,比如系统级别的CPU占用率、内存使用率、磁盘I/O和网络I/O等,再比如应用级别以及JVM级别的各类资源使用率指标等。
后端性能测试的场景设计主要包括以下两种方式:
前端性能关注的是浏览器端的页面渲染时间、资源加载顺序、请求数量、前端缓存使用情况、资源压缩等内容,希望借此找到页面加载过程中比较耗时的操作和资源,然后进行有针对性的优化,最终达到优化终端用户在浏览器端使用体验的目的。
业界普遍采用的前端测试方法,是雅虎(Yahoo)前端团队总结的7大类35条前端优化规则,你可以通过雅虎网站查看这些规则,以及对各规则的详细解读。
是指在单元测试阶段就对代码的时间性能和空间性能进行必要的测试和评估,以防止底层代码的效率问题在项目后期才被发现的尴尬。
如果你从事过性能测试相关的工作,一定遇到过这样的场景:系统级别的性能测试发现一个操作的响应时间很长,然后你要花费很多时间去逐级排查,最后却发现罪魁祸首是代码中某个实现低效的底层算法。这种自上而下的逐级排查定位的方法,效率通常都很低,代价也很高。
需要在项目早期,对一些关键算法进行代码级别的性能测试,以防止此类在代码层面就可以被发现的性能问题,遗留到最后的系统性能测试阶段才被发现。
码级性能测试并不存在严格意义上的测试工具,通常的做法是:改造现有的单元测试框架。
最常使用的改造方法是:
压力测试,通常指的是后端压力测试,不断对系统施加压力,并验证系统化处于或长期处于临界饱和阶段的稳定性以及性能指标,并试图找到系统处于临界状态时的主要瓶颈点。所以,压力测试往往被用于系统容量规划的测试。
配置测试,主要用于观察系统在不同配置下的性能表现,通常使用后端性能测试的方法:
并发测试,指的是在同一时间,同时调用后端服务,期间观察被调用服务在并发情况下的行为表现,旨在发现诸如资源竞争、资源死锁之类的问题。
“集合点并发”:为了达到准确控制后端服务并发数的目的,我们需要让某些并发用户到达该集合点时,先处于等待状态,直到参与该集合的全部并发用户都到达时,再一起向后端服务发起请求。简单地说,就是先到的并发用户要等着,等所有并发用户都到了以后,再集中向后端服务发起请求。
在实际项目中,我建议在要求的并发数上进行适当放大,比如要求的并发数是100,那我们集合点并发数可以设置为120。
可靠性测试,是验证系统在常规负载模式下长期运行的稳定性。虽然可靠性测试在不同公司的叫法不同,但其本质就是通过长时间模拟真实的系统负载来发现系统潜在的内存泄漏、链接池回收等问题
真实环境下的实际负载,会有高峰和低谷的交替变化,我们会每12小时模拟一个高峰负载,两个高峰负载中间会模拟一个低峰负载,依次循环3-7天,形成一个类似于“波浪形”的系统测试负载曲线。同样地,可靠性测试也会持续3-7天。
千万不要简单地把使用后端性能测试工具等同于后端性能测试,它只是后端性能测试中的一个必要步骤而已。
完整的后端性能测试应该包括性能需求获取、性能场景设计、性能测试脚本开发、性能场景实现、性能测试执行、性能结果报告分析、性能优化和再验证。
使用性能测试工具获得性能测试报告只是性能测试过程中的一个必要步骤而已,而得出报告的目的是让性能测试工程师去做进一步的分析,以得出最终结论,并给出性能优化的措施。
1.我们把这些基于协议模拟用户行为的脚本称为虚拟用户脚本,而把开发和产生这些脚本的工具称为虚拟用户脚本生成器。
2.我们把实际发起测试负载的机器称为压力产生器。
3.有了多台压力产生器,那就需要一个专门的控制器来统一管理与协调这些压力产生器,我们把这个专门的控制器称为压力控制器。
4.后端性能测试工具需要监控应用服务器、数据库服务器、消息队列服务器、缓存服务器等各种资源的占用率。我们通常把完成监控和数据收集的模块称为系统监控器。
5.后端性能测试工具通常能够基于该报告生成各类指标的各种图表,还能将多个指标关联在一起进行综合分析来找出各个指标之间的关联性。我们把完成这部分工作的模块称为测试结果分析器。
首先,后端性能测试工具会基于客户端与服务器端的通信协议,构建模拟业务操作的虚拟用户脚本。
然后,开发完成了虚拟用户脚本之后,后端性能测试工具会以多线程或多进程的方式并发执行虚拟用户脚本,来模拟大量并发用户的同时访问,从而对服务器施加测试负载。
接着,在施加测试负载的整个过程中,后端性能测试工具除了需要监控和收集被测系统的各种性能数据以外,还需要监控被测系统各个服务器的各种软硬件资源。
最后,测试执行完成后,后端性能测试工具会将系统监控器收集的所有信息汇总为完整测试报告。
LoadRunne 和JMeter
LoadRunner:
? 传统软件企业采用,(按照并发用户数收费的,并发用户数越高收费也越贵)
传统软件企业,需要测试的并发用户数并不会太高,通常是在几百到十几万这个数量级,
LoadRunner对海量并发的测试支持并不太好;
JMeter
? 互联网企业的并发用户请求数量很高,很多软件都会达到百万,甚至是千万的级别。
? 开源的JMeter中,用户完全可以根据需求进行扩展
这块我不做关注,略
获取这些测试需求时性能测试中最难的两个工作之一。另一个最难的工作是,测试结果分析与性能问题定位。而其他类似性能测试脚本开发、场景设计等工作看起来很有技术含量,但实际都是一些相对机械性的重复工作。
对于性能测试设计人员来说,到底如何获得这个明确的性能需求呢?
你可以采用80/20原则对高峰时段的用户负载进行建模
性能测试需求的定义与计划非常复杂,牵涉到项目的方方面面,不可能通过阅读一两篇文章就快速掌握这一技能,需要不断地沉淀在实战中获得的经验。
从宏观角度,我把整个性能测试过程划分成了五个阶段:性能需求收集以及负载计划制定、录制并增强虚拟用户脚本、创建并定义性能测试场景、执行性能测试场景,以及分析测试报告。
在我看来,这五个阶段最难的两部分工作分别是:明确具体的性能测试需求,以及测试结果分析与性能问题定位。因为这两部分工作,要大量依赖于测试工程师的能力以及经验积累。所以,就像一名优秀的医生一样,优秀的测试工程师,需要在实际的工程项目中不断积累和总结经验。
LoadRunner开发虚拟用户脚本主要包括以下四个步骤:
如果已经知道被测系统采用的协议,则可以跳过这个步骤。
要将这些操作步骤在虚拟用户脚本中封装成“事务”(Transaction)。
封装为“事务”的目的是统计响应时间,因为LoadRunner中的响应时间都是以“事务”为单位的。
在录制脚本的过程中,我强烈建议直接对发起后端调用的操作添加事务定义,而不要等到脚本生成后再添加。因为LoadRunner脚本的可读性并不好,在录制完的脚本中添加事务定义的难度会很大。
在录制过程中,直接添加事务操作也很简单,主要包括如下三步:
这样你刚才执行GUI操作的脚本就会被lr_start_transaction(“事务名称”)和lr_end_transaction(“事务名称”,LR_AUTO)包围起来,也就完成了添加事务的定义。
录制的脚本不能直接使用,我们还需要对录制的脚本做以下处理:
思考时间:两次发起请求之间往往会有一个时间的间隔。(了让虚拟用户脚本能够更真实地模拟实际用户的行为,我们就需要在两个事务之间加入一定的等待时间。)
在实际项目中,一般先粗略估计一个值(比如15 s),然后在实际执行负载场景的过程中,再根据系统吞吐量调整。
调整思考时间时,无需逐行修改虚拟用户脚本代码,可以在Run-time Settings(运行时设置)中很方便地完成。
凡是参数文件中使用的测试数据都需要在执行性能测试前,在被测系统中事先准备好
关联的主要作用是,取出前序调用返回结果中的某些动态值,传递给后续的调用。
LoadRunner提供了功能强大的关联函数web_reg_save_param()。这个关联函数支持多种动态值的获取方式,用得最多的是基于“前序字符串匹配”加上“后续字符串匹配”的方式。其中,字符串匹配,支持正则表达式。
需要特别注意的是web_reg_save_param()函数是注册型函数,必须放在获取动态值所属的请求前面,相当于先声明,后调用。
性能测试脚本,不像功能测试脚本那样需要加入很多的断言,往往只在一些关键步骤后加入很少量的检查点即可。这些检查点的主要作用是,保证脚本按照原本设计的路径执行。
最常用的检查点函数是web_reg_find(),它的作用是通过指定左右边界的方式“在页面中查找相应的内容”。
只有上述四个测试全部通过,虚拟用户脚本才算顺利完成
根据前面的测试场景,进行图形操作即可
点击执行即可,还可以监控测试执行的过程
性能测试报告的解读,需要丰富的系统架构、性能理论以及大量实战经验的积累。这个话题已经超出了我今天要分享的范围,所以我也就不再继续展开了。
这里有留言推荐 wrk测试工具的,先记录下来
性能基准测试,通常被称为Performance Benchmark Test,是每次对外发布产品版本前必须要完成的测试类型。通过执行固定的性能测试场景得到系统的性能测试报告,然后与上一版本发布时的指标进行对比,如果发现指标有“恶化”的趋势,就需要进一步排查。
恶化趋势表现:
以最常见的事务响应时间变慢为例,和你说明一下排查方法。
假设,通过性能基准测试的比较结果得知,用户登录的响应时间从2 s变成了4 s。
通过对每个预发布版本的性能基准测试,我们可以保证新发布系统的整体性能不会下降,这也就是性能基准测试最终要达到的目的。
从性能基准测试的设计角度来看,你需要特别注意以下三点:
稳定性测试,又称可靠性测试,主要是通过长时间(7*24小时)模拟被测系统的测试负载,来观察系统在长期运行过程中是否有潜在的问题。
稳定性测试,通常直接采用性能基准测试中的虚拟用户脚本,但是性能测试场景的设计和性能基准测试场景会有很大不同:
一般是采用“波浪式”的测试负载,比如先逐渐加大测试负载,在高负载情况下持续10多个小时,然后再逐渐降低负载,这样就构成了一个“波浪”,整个稳定性测试将由很多个这样的波浪连续组成。
稳定性测试成功完成的标志,主要有以下三项:
由于稳定性测试执行的时间成本很高,往往需要花费3~7天的时间,所以我们一般是在其他所有测试都已经完成,并且所有问题都已经修复之后才开始稳定性测试。
虽然很多时候,尤其是产品版本已经逐渐走向成熟期时,稳定性测试并不会发现问题,但是千万不要小看稳定性测试带来的价值。因为稳定性测试一旦发现问题,那么这些问题都是很严重而且非常隐蔽的大问题。
并发测试,是在高并发情况下验证单一业务功能的正确性以及性能的测试手段。
高并发测试一般使用思考时间为零的虚拟用户脚本来发起具有“集合点”的测试。
并发测试,往往被当作功能测试的补充,主要用于发现诸如多线程、资源竞争、资源死锁之类的错误。
加入“集合点”一般有两种做法:
容量规划测试,是为了完成容量规划而设计执行的测试。
容量规划的主要目的是,解决当系统负载将要达到极限处理能力时,我们应该如何通过垂直扩展(增加单机的硬件资源)和水平扩展(增加集群中的机器数量)增加系统整体的负载处理能力的问题。
容量规划测试具体要怎么做呢?
使用性能基准测试中的虚拟用户脚本,以及各个业务操作脚本的百分比,压测单机部署的被测系统。我们会采用人工的方式不断增加测试负载直到单机系统的吞吐量指标到达临界值,由此就可以知道单台机器的处理能力。
理论上讲,整个集群的处理能力将等于单台机器的处理能力乘以集群的机器数,但是实际情况并不是这样。实际的集群整体处理能力一定小于这个值,但具体小多少就是要靠实际的测试验证了。
附上华为云的性能测试策略与指标分析
原文:https://www.cnblogs.com/wfer/p/14244385.html