性能测试导读
在性能测试领域,最重要的是掌握性能测试思想,很多人用一个工具用习惯了,换一个工具就不会做性能测试了,这样换了一个公司或一个项目不用这个工具,以前的技能就排不上用场了,所以我们学习性能测试重在流程,思想,不是脚本的录制,而是脚本的编写和优化,不是单纯的工具使用,而是掌握性能测试中涉及的概念、参数,性能测试环境准备过程中的策略,问题分析,性能调优,这些思想如果能够灵活的掌握,深入的理解,无论处理那个场景,就算换个环境换个个工具,也能够快速的上手和适应,本文的目的在于引导大家如何进入性能测试领域,如何开始学习,如何进阶,到最终形成一套输入自己独有的性能测试思维和方法。
本文的主要内容包括:
(1) 性能测试基础。介绍性能需要了解的基本原理、概念,基于性能测试的指标,涉及到的知识点了解等;
(2) 性能测试执行。介绍如何设计性能测试用例,如何写出高质量的性能测试脚本,如何设置场景策略等。
(3) 性能测试分析。介绍学习常用的性能测试分析方法,常见的性能测试问题,性能影响的因素,如何进行性能调优;
(4) 实战分析。说明实际项目中的性能测试整体流程,从需求分析到撰写测试报告的一整套流程方法讲解。
一、 性能测试基础篇
性能测试和功能测试,自动化测试有一定的区别,功能测试了解具体的业务逻辑,还有具体的测试方法,如等价类、边界值等,自动化则需要有编程基础,需要了解自动化测试框架,PC端的自动化需要了解如python+selenium的测试框架,APP端自动化需要了解python+APPIUM测试框架,而做好性能测试需要了解的知识面会更广,需要了解TCP/IP、网络路由、编程语言如C、python、服务器指标监控如Nmon、接口测试、服务器链接配置、主流程数据库知识(redis、mysql、oracle等),涉及软硬件,多端知识,有一些知识不了解,性能测试就很难做好。
性能测试的基本类型分为基准测试、压力测试、负载测试、并发测试、配置测试、可靠性测试,负载测试也称为容量测试,是指对系统不断地增加压力或增加一定压力下的持续时间,直到系统的某项或多项性能指标达到安全临界值,例如某种资源已经达到饱和状态等
,检查软件在一定时期内,最大支持多少并发用户数,TPS、吞吐率、事物成功率等;并发测试是多个用户同时访问同一个应用、同一个模块或者数据记录时是否存在死锁或者其他性能问题,一般根据需求文档来进行标准化测试,验证是否满足要求;负载测试和并发测试主要区别是负载测试在一定压力范围内持续增大并发用户,会持续一段时间,检查系统资源达到饱和的情况下的,系统运行的稳定性,而并发测试则只用测试需求文档的标准是否满足,不关注系统稳定性,且不会持续很长时间。
常见的性能需要关注的性能指标有:响应时间、吞吐率、并发数、资源利用率、TPS、思考时间、PV、UV等,下面对这些概念分别进行介绍。
1、响应时间:一般性能测试中需要测量和关注的是事务响应时间,事务可能由一系列请求组成,事务的响应时间主要针对用户而言,属于宏观上的概念,是为了向用户说明业务响应时间而提出的。例如:跨行取款事务的响应时间就是由一系列的请求组成的。事务响应时间和后面的业务吞吐率都是直接衡量系统性能的参数。
2、吞吐率:通常用来指单位时间内网络上传输的数据量,也可以指单位时间内处理的客户端请求数量。它是衡量网络性能的重要指标。但是从用户或业务角度来看,吞吐率也可以用“请求数/秒”或“页面数/秒”、 “业务数/小时或天”、 “访问人数/天”、 “页面访问量/天”来衡量。例如在银行卡审批系统中,可以用“千件/每小时”来衡量系统的业务处理能力。
3、并发数:并发数有3个概念,很容易弄混淆,一般包括并发用户数、在线用户数、系统用户数,一般和系统性能息息相关的是并发用户数,指的是同一时刻超多的用户去执行同个动作,比如登陆、访问等,具体区别大家可参考下图:
4、资源利用率:包括CPU、内存、磁盘I/O等信息,执行性能测试时需要同步监控服务器信息,结合响应时间、并发数、TPS等进行监控,一般当CPU、内存超过一定百分比如90%或者资源使用率猛然增加,这时系统一般出现了瓶颈;
5、TPS:Transactions Per Second,每秒通过的事务数,在loadrunner中可以设置开始事务和结束事务的节点,开始和结束节点中间的脚本执行完即算一个事务运行结束,loadrunner还可以通过如下方式进行TPS监控
6、点击数:每秒钟用户向WEB服务器提交的HTTP请求数。这个指标是WEB应用特有的一个指标:WEB应用是"请求-响应"模式,用户发出一次申请,服务器就要处理一次,所以点击是WEB应用能够处理的交易的最小单位。如果把每次点击定义为一个交易,点击率和TPS就是一个概念。容易看出,点击率越大,对服务器的压力越大。点击率只是一个性能参考指标,重要的是分析点击时产生的影响。需要注意的是,这里的点击并非指鼠标的一次单击操作,因为在一次单击操作中,客户端可能向服务器发出多个HTTP请求;
7、思考时间:用户每个操作后的暂停时间,或者叫操作之间的间隔时间,此时间内是不对服务器产生压力的,跟自动化里面的sleep函数效果一样,思考时间可以模拟特定的场景,比如需要模拟用户实际正常的操作习惯,如查询站点页面信息时间,这时就会用到等待时间;
8、PV值:访问一个URL,产生一个PV(Page View,页面访问量),每日每个网站的总PV量是形容一个 网站规模的重要指标。即页面浏览量或点击量,用户每次刷新即被计算一次。PV反映的是浏览某网站的页面数,所以每刷新一次也算一次。就是说PV与来访者的数量成正比,但PV并不是页面的来访者数量,而是网站被访问的页面数量;
9、UV值:作为一个独立的用户,访问站点的所有页面均算作一个UV(Unique Visitor,用户访问),访问网站的一台电脑客户端为一个访客。00:00-24:00内相同的客户,网站判断来访电脑的身份是通过来访电脑的cookies实现的。如果更换了IP后但不清除cookies,再访问相同网站,该网站的统计中UV数是不变的。
性能测试最具代表性的工具是Loadrunner,但是所有工具需要理解的性能测试理念都是相同的,比如我们需要掌握性能测试中最重要的几个概念,事务、参数化、关联、检查点、集合点,事务又称为Transaction ,事务(Transaction)是这样一个点,我们为了衡量某个action(动作)的性能,需要在action的开始和结束位置插入这样一个“范围”,这就定义了一个transaction。 参数化是用参数来替换一些常量,以是一个文件;内部生成的变量;源于数据库中的查询结果,如用户名,密码,日期,用户ID、数据库中存在的数据。关联是业务操作依赖与上一个操作的返回结果和数据,而且数据是变化的,就需要进行数据关联。如一般购物网站加入购物车需要依赖登陆返回的token值,又如:验证码。集合点是同一时刻发起的用户操作,集合点可以控制各个vuser在同一时刻执行任务。借助集合点,可以在LR中实现真正意义的完全一样的并发。检查点作用是判断操作是否成功,检查点是必不可少的。loadrunner中可以设置文本检查点和图片检查点等。
二、 性能测试执行篇
首先来看一下性能测试的基本流程,流程图如下:
1、 需求分析
性能需求分析是整个性能测试工作开展的基础,如果连性能的需求都没弄清楚,后面的性能测试执行其实是没有任何意义的,而且性能需求分析做的好不好直接影响到性能测试的结果。
一些性能测试人员常犯的错误就是测试一开始就直接用工具对系统进行加压,没有弄清楚性能测试的目的,稀里糊涂做完了以后也不知道结果是否满足性能需求。市面上的书籍也大都是直接讲性能测试工具如LR,jmeter如何使用,导致很多新手一提到性能测试就直接拿工具来进行录制回放,使得很多人认为会使用性能测试工具就等于会性能测试了,殊不知工具其实只是性能测试过程中很小的一部分。
在需求分析阶段,测试人员需要与项目相关的人员进行沟通,收集各种项目资料,对系统进行分析,建立性能测试数据模型,并将其转化为可衡量的具体性能指标,确认测试的目标。所以性能测试需求分析过程是繁杂的,需要测试人员有深厚的性能理论知识,除此之外还需要懂一些数学建模的知识来帮助我们建立性能测试模型。
比如我们拿一个电商站点的搜索模块进行需求分举例,产品经理要提出一个性能需求,必须要结合实际网站的流量或者预估网站将来会达到多大的流量峰值来进行分析,一般我们采用80~20原则通过PV值计算目标并发用户数的公式是什么,如果系统最高一天的首页访问的PV值是1000000,请根据80~20原则计算出实际的并发用户数,计算如下:假设用户在前台的一次操作,仅产生一次pv。
(1)最差情况:1000000个用户同时发起请求,那么并发用户数应为1000000;
(2)最好情况:1000000个用户在时间上均匀地发起请求。那么并发用户数为1000000/24*60*60=11.57。折合一分钟内有694个请求。
(3)80~20原则:但是在现实中,以上两种情况发生的概率很小。根据统计学原理,采用80~20原则计算并发用户数。
结果:1000000*0.8/(8*60*60*0.2)=46.29,即每秒有47个用户并发。那么产品经理就会提出要求,232个并发5秒内响应的需求指标。
2、 性能测试准备
(1) 系统运行环境:这个通常就是我们的测试环境,有些时候需求比较多,做性能测试担心把环境搞跨了影响其它的功能测试,可能需要重新搭建一套专门用来做性能测试的环境。
(2) 执行机环境:这个就是用来生成负载的执行机,通常需要在物理机上运行,而物理机又是稀缺资源,所以我们每次做性能测试都需要提前准备好执行机环境。
(3) 测试场景设计:根据性能需求分析来设计符合用户使用习惯的场景,场景设计的好不好直接影响到性能测试的效果。
(4) 性能工具准备:如负载工具可以根据需求分析和系统特点选择合适的负载工具,比如LR、Jmeter或galting等
(5) 监控工具:准备性能测试时的服务器资源、JVM、数据库监控工具,以便进行后续的性能测试分析与调优。
3、 性能测试执行
(1)人工边执行边分析
通常我们做性能测试都是人工执行并随时观察系统运行的情况、资源的使用率等指标。性能测试的吸引力之一就在于它的不可预知性。当我们在做性能测试的时候遇到跟预期不符的情况很正常,这个时候需要冷静的分析。但这个过程可能会很慢长,需要不断的调整系统配置或程序代码来定位问题,耗时耗人力。特别是在当前敏捷开发模式比较流行的大环境下,版本发布非常频繁且版本周期短(通常1~2周一个版本),没有那么长的时间来做性能测试。
(2)无人值守执行性能测试
无人值守是最理想化的目标,目前我们也朝着这个方向努力。无人值守不是说没有人力介入,而是把人为的分析和执行过程分离,执行过程只是机器服从指令的运行而已。通常测试环境在白天比较繁忙,出现性能问题及定位难度较大且会影响功能测试。所以一般性能测试最好在晚上或周末进行,在相对较安静的条件有利于测试结果的稳定性。这种方法也相对比较适合敏捷的模式,不需要人工一直守着。只需要在拿到结果后进行分析就好了。同进,这种方式对测试人员能力的要求比较高,需要我们能进行自动化的收集各种监控数据、生成报表便于后续分析。
具体执行的策略有很多,比如验证性能需求的指标是否达标,有常用的两种方式。方法一:多次迭代测试得出。web测试以5秒响应为基准,首先设置初始并发用户数,如n个,当响应时间小于5秒,则增加n个,再次迭代运行并发场景,反之减少n值,直到响应时间接近于5秒,如果此时的Vuser数量为m个,则认为该业务场景的最大并发用户数为m个;方法二:Vuser逐步加载得出;在Run Load Tests组件中增加业务场景,Start Vusers设置逐步加载模式,如5秒加载5个Vuser,Stop Vuser中设置逐步释放模式,如5秒释放5个Vuser,运行一分钟,得出的测试结果将Running Vuser和Response Time图表结合进行分析,最终得出5秒左右响应的并发用户数。
三、 性能测试分析篇
举一个和大家现实生活相关的例子,大家就能够对性能测试有一个很直观的认识,并且能够从这个例子中看出一些性能测试分析的方法。
和绝大部分人一样,小白每天都要乘坐地铁上下班,那么就拿地铁来分析,再次深刻理解下性能。早上乘坐地铁上班,最典型的就是北京地铁1、5、10、13号线等,人多得简直没法形容!为了方便理解分析,先做如下假设。某地铁站进站只有3个刷卡机。人少的情况下,每位乘客很快就可以刷卡进站,假设进站需要1s。乘客耐心有限,如果等待超过30min,就会暴躁、唠叨,甚至选择放弃。按照上述的假设,最初会出现如下的场景:
场景一:只有1名乘客进站时,这名乘客可以在1s的时间内完成进站,且只利用了一台刷卡机,剩余2台等待着。
场景二:只有2名乘客进站时,2名乘客仍都可以在1s的时间内完成进站,且利用了2台刷卡机,剩余1台等待着。
场景三:只有3名乘客进站时,3名乘客还能在1s的时间内完成进站,且利用了3台刷卡机,资源得到充分利用。
想到这里,小白越来越觉得有意思了,原来技术与生活这么息息相关,真的可以快乐学习哦。随着上班高峰的到来,乘客也越来越多,新的场景也慢慢出现了。
场景四:A、B、C三名乘客进站,同时D、E、F乘客也要进站,因为A、B、C先到,所以D、E、F乘客需要排队,等A、B、C三名乘客进站完成后才行。那么,A、B、C乘客进站时间为1s,而D、E、F乘客必须等待1s,所以他们3位在进站的时间是2s。
通过上面这个场景可以发现,每秒能使3名乘客进站,第1s是A、B、C,第2s是D、E、F,但是对于乘客D、E、F来说,“响应时间”延长了。
场景五:假设这次进站一次来了9名乘客,根据上面的场景,不难推断出,这9名乘客中有3名的“响应时间”为1s,有3名的“响应时间”为2s(等待1s+进站1s),还有3名的“响应时间”为3s(等待2s+进站1s)。
场景六:假设这次进站一次来了10名乘客,根据上面的推算,必然存在1名乘客的“响应时间”为4s,如果随着大量的人流涌入进站,可想而知就会达到乘客的忍耐极限。
场景七:如果地铁正好在火车站,例如,著名的北京西站、北京站。每名乘客都拿着大小不同的包,有的乘客拿的包太大导致卡在刷卡机那(堵塞),这样每名乘客的进站时间就会又不一样。
小白突然想到,貌似很多地铁进站的刷卡机有加宽的和正常宽度的两种类型,那么拿大包的乘客可以通过加宽的刷卡机快速进站(增加带宽),这样就能避免场景七中的现象。
场景八:进站的乘客越来越多,3台刷卡机已经无法满足需求,于是为了减少人流的积压,需要再多开几个刷卡机,增加进站的人流与速度(提升TPS、增大连接数)。
场景九:终于到了上班高峰时间了,乘客数量上升太快,现有的进站措施已经无法满足,越来越多的人开始抱怨、拥挤,情况越来越糟。单单增加刷卡机已经不行了,此时的乘客就相当于“请求”,乘客不是在地铁进站排队,就是在站台排队等车,已经造成严重的“堵塞”,那么增加发车频率(加快应用、数据库的处理速度)、增加车厢数量(增加内存、增大吞吐量)、增加线路(增加服务的线程)、限流、分流等多种措施便应需而生。
上述这个例子很生活了包括了从性能需求提出,性能指标分析,性能测试执行到性能测试分析,通过9个场景能够看出什么原因引起的性能问题,怎么才能优化性能问题,非常生动形象的概括出来了。
下面总结了一些影响性能问题的常见的点,并对性能调优一般方法做相关的说明:
(1)超多的HTTP请求:在浏览器(客户端)和服务器发生通信时,就已经消耗了大量的时间,尤其是在网络情况比较糟糕的时候,这个问题尤其的突出。一个正常HTTP请求的流程简述:如在浏览器中输入"www.xxxxxx.com"并按下回车,浏览器再与这个URL指向的服务器建立连接,然后浏览器才能向服务器发送请求信息,服务器在接受到请求的信息后再返回相应的信息,浏览器接收到来自服务器的应答信息后,对这些数据解释执行。而当我们请求的网页文件中有很多图片、CSS、JS甚至音乐等信息时,将会频繁的与服务器建立连接,与释放连接,这必定会造成资源的浪费,且每个HTTP请求都会对服务器和浏览器产生性能负担。网速相同的条件下,下载一个100KB的图片比下载两个50KB的图片要快。所以,请减少HTTP请求。解决办法:合并图片(css sprites),合并CSS和JS文件;图片较多的页面也可以使用 lazyLoad 等技术进行优化。
(2)使用JSON格式进行数据交换:JSON是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式。同时,JSON是 JavaScript原生格式,这意味着在 JavaScript 中处理 JSON数据不需要任何特殊的 API 或工具包。与XML序列化相比,JSON序列化后产生的数据一般要比XML序列化后数据体积小,所以在Facebook等知名网站中都采用了JSON作为数据交换方式。
(3)使用CDN加速(内容分发网络):其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。实时性不太好是CDN的致命缺陷。随着对CDN需求的逐渐升温,这一缺陷将得到改进,使来自于远程服务器的网络内容网页与复本服务器或缓存器中的网页保持同步。解决方法是在网络内容发生变化时将新的网络内容从服务器端直接传送到缓存器,或者当对网络内容的访问增加时将数据源服务器的网络内容尽可能实时地复制到缓存服务器。
(4)压缩图片和使用图片Sprite技术:现在由于工作的细分,专业的前端工程师已经少有机会去切图了,可是关于图片压缩还是得略微了解,一般图片压缩的方式有:缩小图片分辨率、.改变图片格式、降低图片保存质量。
(5)数据库调优:总的来说分为以下三部分:
SQL调优:这是最常用、每一个技术人员都应该掌握基本的SQL调优手段(包括方法、工具、辅助系统等)。这里以MySQL为例,最常见的方式是,由自带的慢查询日志或者开源的慢查询系统定位到具体的出问题的SQL,然后使用explain、profile等工具来逐步调优,最后经过测试达到效果后上线。
架构层面的调优:这一类调优包括读写分离、多从库负载均衡、水平和垂直分库分表等方面,一般需要的改动较大,但是频率没有SQL调优高,而且一般需要DBA来配合参与。那么什么时候需要做这些事情?我们可以通过内部监控报警系统(比如Zabbix),定期跟踪一些指标数据是否达到瓶颈,一旦达到瓶颈或者警戒值,就需要考虑这些事情。通常,DBA也会定期监控这些指标值。
连接池调优:我们的应用为了实现数据库连接的高效获取、对数据库连接的限流等目的,通常会采用连接池类的方案,即每一个应用节点都管理了一个到各个数据库的连接池。随着业务访问量或者数据量的增长,原有的连接池参数可能不能很好地满足需求,这个时候就需要结合当前使用连接池的原理、具体的连接池监控数据和当前的业务量作一个综合的判断,通过反复的几次调试得到最终的调优参数。
(6)代码:代码最容易引起技术人员的忽视。很多技术人员拿到一个性能优化的需求以后,言必称缓存、异步、JVM等。实际上,第一步就应该是分析相关的代码,找出相应的瓶颈,再来考虑具体的优化策略。有一些性能问题,完全是由于代码写的不合理,通过直接修改一下代码就能解决问题的,比如for循环次数过多、作了很多无谓的条件判断、相同逻辑重复多次等
(6)缓存:其中本地缓存(HashMap/ConcurrentHashMap、Ehcache、Guava Cache等),缓存服务(Redis/Tair/Memcache等)。什么情况适合用缓存?考虑以下两种场景:短时间内相同数据重复查询多次且数据更新不频繁,这个时候可以选择先从缓存查询,查询不到再从数据库加载并回设到缓存的方式。此种场景较适合用单机缓存。高并发查询热点数据,后端数据库不堪重负,可以用缓存来扛。如果数据量小,并且不会频繁地增长又清空(这会导致频繁地垃圾回收),那么可以选择本地缓存。具体的话,如果需要一些策略的支持(比如缓存满的逐出策略),可以考虑Ehcache;如不需要,可以考虑HashMap;如需要考虑多线程并发的场景,可以考虑ConcurentHashMap。其他情况,可以考虑缓存服务。目前从资源的投入度、可运维性、是否能动态扩容以及配套设施来考虑,我们优先考虑Tair。除非目前Tair还不能支持的场合(比如分布式锁、Hash类型的value),我们考虑用Redis。
四、 性能测试实战分析篇
下面总结实战测试过程中经常会遇到的常用的执行方法和分析方法,大家可以举一反三灵活运用。
1、 如何得到最大并发用户数,有两种方法,(1)多次迭代得出;(2)Vuser逐步加载得出;
2、 最直接的可通过Web Page Diagostics来分析每个链接的响应时间、size来判断网页
的瓶颈在哪里,如下图所示:
从上图可以直观的看到每个链接的下载时间,靠前的均是图片问题,而且size都超过了100KB,需要进行图片压缩处理;
3、 判断应用程序的问题
如果系统由于应用程序代码效率低下或者系统结构设计有缺陷而导致大量的上下文切换(context switches/sec显示的上下文切换次数太高)那么就会占用大量的系统资源,如果系统的吞吐量降低并且CPU的使用率很高,并且此现象发生时切换水平在15000以上,那么意味着上下文切换次数过高。
从图的整体看context switches/sec变化不大,throughout曲线的斜率较高,并且此时的context switches/sec已经超过了15000。程序还是需要进一步优化。
4、 判断判断CPU瓶颈
processor queue length显示的队列长度保持不变(>=2)个并且处理器的利用率%Processor time超过90%,那么很可能存在处理器瓶颈。如果发现processor queue length显示的队列长度超过2,而处理器的利用率却一直很低,或许更应该去解决处理器阻塞问题,这里处理器一般不是瓶颈。
%processor time平均值大于95,processor queue length大于2,可以确定CPU瓶颈,此时的CPU已经不能满足程序需要,急需扩展。
5、 判断内存泄露问题
内存问题主要检查应用程序是否存在内存泄漏,如果发生了内存泄漏,process\private bytes计数器和process\working set 计数器的值往往会升高,同时avaiable bytes的值会降低。内存泄漏应该通过一个长时间的用来研究分析所有内存都耗尽时,应用程序反应情况的测试来检验。
图中可以看到该程序并不存在内存泄露的问题,内存泄露问题经常出现在服务长时间运转的时候,由于部分程序对内存没有释放,而将内存慢慢耗尽。提醒大家对系统稳定性测试的关注。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix