书名:全栈性能测试修炼宝典 JMeter实战(第2版)
ISBN:A20200896
本书由人民邮电出版社发行数字版。版权所有,侵权必究。
您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。
我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。
如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。
编 著 陈志勇 刘 潇 钱 琪
责任编辑 张 涛
人民邮电出版社出版发行 北京市丰台区成寿寺路11号
邮编 100164 电子邮件 315@ptpress.com.cn
网址 http://www.ptpress.com.cn
读者服务热线:(010)81055410
反盗版热线:(010)81055315
本书全面介绍了软件性能测试中的实战技术和JMeter的应用知识。本书分4篇10章:基础篇(第1章)主要讲解性能测试的理论和如何做好性能测试;工具篇(第2~4章)介绍了利用JMeter进行性能测试脚本开发,如利用HTTP在JMeter中进行性能测试脚本开发;实践篇(第5~8章)详细讲解了性能监控与诊断分析,通过实践项目引导读者进行性能测试工作,包括诊断问题、分析与调优;提升篇(第9~10章)讲解如何基于JMeter做测试开发、利用容器技术提高测试效率。
本书讲解通俗易懂,适合测试工程师、测试项目负责人、开发工程师、性能测试爱好者阅读,也适合作为大专院校相关专业师生的学习用书和培训学校的教材。
《全栈性能测试修炼宝典:JMeter实战》于2016年9月面市。承蒙大家厚爱,本书有幸获得“异步图书十佳”称号,到目前还保持着顽强的生命力,证明本书对大家来说还是有用的。这让我很欣慰。几年过去了,技术在发展,业务在变化,系统都在上云,测试、监控、运维从自动化往智能化发展。我在不断学习的过程中有些总结想通过本书的修订与大家分享。
移动互联的普及催生了大数据,即将爆发的5G生态将会加速万物互联,数据量将呈几何级增长。企业需要更快、更准、更稳定的系统来处理这些数据,系统性能在其中起着不可忽视的作用,性能测试依然大有可为。
性能测试的目的是检查系统有无性能风险,找出系统性能变化的趋势,为运营人员提供数据参考;定位性能问题,进行系统性能优化。对于性能测试工程师来说,性能测试既是一个持续改进的过程,也是一份充满挑战的工作,会涉及硬件平台、操作系统、数据库、缓存、中间件、应用架构、系统程序等方面的知识,广度与深度并重。这也对从事这项工作的工程师提出了更高的要求,当然,高要求也铸就了性能测试工程师的高价值。
IT更新速度快,测试从业者不进则退,不想被淘汰就需要适应技术潮流,不断更新自己的技术体系,让自己具备竞争力。“工欲善其事,必先利其器”,性能测试的开展少不了工具的支持,本书以JMeter(5.0及以上版本)为例来讲解性能测试脚本的开发。要解决问题,需要深入了解问题的本质,本书将继续讲解如何定位问题,如何进行性能优化。从前端到后端,从物理机到容器,从理论到实践,与大家一起分享自己学到的知识。
在此感谢我的家人,感谢读者,感谢支持我的朋友!
陈志勇(天胜)
性能测试人员
DevOps开发者
于上海
早期,我们把录制脚本、制造负载当作性能测试;后来,我们把定位、分析问题当作性能测试的核心价值;前几年,我们希望性能测试不仅能够定位、分析问题,还要把握系统性能变化趋势,帮助解决性能问题,给出专业的优化建议;现在,云计算已深入应用系统中,性能测试工程师最好能够基于云来开展性能测试,让系统在云上“跑得”更顺畅。
性能测试是测试行业颇具技术含量的工作,出于行业的历史原因,性能测试工程师一直短缺,不少功能测试人员担任了性能测试工作的角色,他们没有系统地学习过性能测试知识,没能打下坚实的技术功底,这直接导致了性能测试人员的技术水平不高、从业人员水平参差不齐的现象。很多性能测试工程师停留在测试脚本的开发上。这个现象是可以改变的。只要不断学习,就可以改变。
(1)了解性能测试理论。通过学习这部分内容,您将加深对性能测试的认识。
(2)学会开发多种协议的性能测试脚本。本书讲解了多种协议的性能测试脚本开发过程,让您可以快速上手性能测试。
(1)JMeter从2.x升级到5.x。
(2)性能监控升级。除了常规监控手段,本书还增加了全链接监控。
(3)诊断升级。本书介绍诊断思路、方法、工具,从原理到实践一步到位。
(4)实战升级。本书诊断及调优过程讲解得更细致。
(5)测试开发。本书教大家如何“造轮子”,大家再也不用怕无工具可用。
(6)增加工程能效内容,如容器部署环境、容器部署负载、Kubernetes部署负载等。
本书由浅入深地讲解性能测试各方面的知识,读者可以根据自身需求关注不同部分的内容。
本书读者包括但不限于以下群体:
本书分4篇。
基础篇
第1章讲解性能测试理论,以及如何做好性能测试。
工具篇
本篇讲解如何利用JMeter来进行性能测试脚本开发,用示例介绍几种不同协议的脚本开发。
第2章以HTTP为例讲解如何在JMeter中进行性能测试脚本开发。
第3章用示例讲解几种不同协议的脚本开发。
第4章用示例讲解如何利用JMeter发生负载,如何进行测试监听。
实践篇
本篇详细讲解性能监控与诊断分析。通过实践项目引导读者进行性能测试工作,包括如何诊断问题和如何分析性能,以及性能调优。
第5章讲解如何进行性能监控、如何诊断,这是每一位性能测试工程师都要掌握的基础知识。
第6章讲解系统性能调优有哪些方法,以及怎么做。读者需掌握系统调优的方法并进行举一反三。
第7章运用实例对整个性能测试过程进行讲解,尤其是监控、诊断与调优过程。
第8章讲解前端性能分析技术,如何进行分析,有哪些可以提高效率的分析工具及其应用。
提升篇
本篇讲解如何基于JMeter做测试开发,如何利用容器技术来提高测试效率。
第9章讲解如何基于JMeter进行二次开发、如何用JMeter进行调试。
第10章讲解使用Kubernetes快速部署负载。
性能测试知识面广,虽然作者已经十分认真地写作,由于作者水平有限,书中内容定有不足之处,恳请各位批评指正。
作者联系方式:电子邮箱seling_china@126.com。
作者微信(如下图):
请扫描下面的二维码获取本书配套的实例脚本、实例配置文档:
陈志勇(天胜),从事性能测试多年,《全栈性能测试修炼宝典:JMeter实战》和《持续集成与持续部署实践》的作者,目前从事性能测试、DevOps开发及实施工作。
刘潇,资深测试工程师,擅长性能测试,拥有多年测试开发、性能测试、持续集成及持续部署经验。
钱琪,资深测试工程师,擅长性能测试,目前从事DevOps开发及实施工作,合著有《持续集成与持续部署实践》。
本书由钱琪、刘潇、陈朔审核及校对,手绘图部分由陈楚瑜完成。
感谢广大读者对我们的支持,让你们久等了,谢谢你们!
感谢人民邮电出版社的大力支持!
感谢我们的家人与朋友!
作者
从本章你可以学到:
全栈正当时
开展全栈性能测试
性能测试技术栈
性能测试相关术语
本书相关内容的约定
从一些测试工程师的招聘需求中我们可以看到,招聘单位对从业者技术的要求越来越高,如要掌握测试理论、持续集成、操作系统、数据库、各类中间件(如Tomcat、MQ、Kafka等),以及具备程序开发能力等。总结起来就是招聘一名全栈测试工程师。IT在变,测试人员要做的就是不断顺应变化。
全栈工程师能够完成产品设计,技术选型,架构落地;可以开发前端和后台程序,并部署到生产环境。一人多用,省成本,完全没有多人配合时的工作推诿和沟通不畅等情况发生,这是创业公司找工程师时,全栈工程师是首选的原因。
大互联网公司的系统平台更复杂,需要更多的角色通力协作完成任务。那是不是全栈工程师在大企业就没有存在的必要了呢?当然有必要。大企业需要从全局考虑来做顶层设计,对于做顶层设计的人来说知识面宽尤为重要。这个人可以不是每一个细分领域的专家,但能够与某些领域专家交流畅顺,能够理会对方意思,尽可能地从全局考虑项目的优化设计,这类人是全栈工程师的典型代表。一位互联网全栈工程师需要掌握包括但不限于如下技术。
如果你是从事大数据方面的开发,还需要掌握的技术如下:Hadoop、Spark、Storm、Flink、Tensorflow、Lucene、Solr、ElasticSearc、Hive/Impala等。当然,你还要熟悉各种算法、统计方法,数学等。
网络平台的崛起,带来巨大的流量,也催生技术的革新。高度集中和融合的系统,结构复杂,技术栈庞大,使测试变得困难。在定位、分析问题时往往会跨技术栈,测试人员靠单一技能并不能较好地完成测试工作。与全栈开发一样,全能型(跨技术栈)测试人才变得抢手,也自然催生出全栈测试概念。
以我们熟悉的支付系统来说,我们在手机上轻轻点一下就把钱支付的看似简单的操作,在其工作流程的背后可能要经过十几个系统,涉及商家、平台、支付企业、银行等多个角色。对这类系统测试时链路长,尤其是做链条测试时,每个系统都要检查,第三方系统还要沟通配合。如对接银行系统的过程中,一般在沟通上最耗时,这也是测试工程师最无力把控的部分。
以前作者在一家支付企业供职,整个支付系统加上金融产品,大大小小共90多个子系统,测试团队部署新版本时都感到头痛,主要风险在版本管理及配置管理方面,特别是进行敏捷开发时,面对多个测试环境(开发环境、集成环境、测试环境、QA验证、模拟环境、生产环境)的情况下,负责功能测试的同事苦不堪言。测试工作除了考验测试人员的业务、技术,还考验测试人员的心态。这个时候能够从容不迫、心静如水的往往都是技术过硬的人。技术过硬的人已经熟悉了技术栈、业务流向、测试环境,能够有条不紊地开展工作。所以这些技术过硬的人往往都是测试团队的主力。
大数据分析、AI、云计算、Devops是当前系统应用的主流技术,这方面的测试对测试人员的技术要求更高。以大数据分析为例,测试数据的制作就是一门学问。测试人员最好能够了解实现功能的算法,设计有针对性的数据。
全栈概念很广,测试人员可以选择一些点突破。如做云计算的测试,要了解虚拟化、容器、虚拟网络、服务编排工具等;做AI测试要了解AI的算法、训练模型。力争储备更多的知识。
在软件行业、互联网行业,软件性能是企业的竞争力。良好的性能才能保证优质的用户体验,谁也不想忍受“蜗牛般”的应用加载,这样的应用会丢失用户。技术在发展,用户对性能的要求在提高,测试人员面对不断更新的技术,庞大的技术栈,性能测试的技术储备也要拓宽。
下面看一下Web请求的生命之旅(见图1-1)。
图1-1 Web请求的生命之旅
(1)用户通过浏览器发出访问请求,浏览器把请求编码,再通过网卡把请求通过互联网传给服务端。
(2)服务端的负载均衡器接收到请求,路由到应用服务器;通常负载均衡器也具备限流的作用。
(3)应用服务器由网卡收到请求,如果网卡繁忙可能会排队;网卡的数据传递给中间件,中间件(如Tomcat)进行协议解码,应用程序才能识别请求;然后由应用程序来处理请求,如果有数据访问或者存储需求则要访问持久层。
(4)持久层负责数据的访问与存储,比如结构数据(狭义地说就是能够存到关系数据库的数据)或者非结构数据(如存到HBase中的数据),如果请求量大,也可能遇到性能问题,这样应用服务就必须等待持久层的响应。
(5)等到持久层的响应后,应用服务把处理好的数据回传给用户。如果网络状态不好,还可能丢包。
(6)用户浏览器收到数据并进行渲染。
我们来看这6步中涉及哪些性能相关技术。
① 浏览器作为展示部分,访问的是前端程序,如今前端程序大量依赖JavaScript,JavaScript程序的性能会影响渲染效率。目前,前端开发的主流框架有React、Vue、Angular等,不良的程序写法会大量占用用户机器的CPU、内存,也有可能“卡死”浏览器。
② 负载均衡器有很多种(Nginx、Haproxy、LVM等),功能大同小异,有些具备缓存功能和多路复用功能。这些功能有些是需要配置的,所以了解负载均衡器的性能配置就有必要了。
③ 中间件帮我们抽象出了通信功能、IO功能、请求监听功能,我们不用从Socket通信开始写程序,不用自己去写监听程序来接收用户的请求;中间件还帮我们实现了线程池;为了适应不同应用场景,中间件还提供了很多优化配置。因此,用好中间件对性能的提升还是很明显的,自然也就要了解中间件的原理,学会分析它、配置它。应用程序处理用户请求,对于Java程序的性能分析,了解HotSpot VM是有帮助的。
④ 持久层可以有很多种,如关系数据库、非关系数据库、缓存、文件系统等,对这些持久化工具的优势与劣势的掌握显然是优化性能所需要的。
⑤ 很多系统都运行在云上。对于云来说,网络是稀有资源,由于网络导致的性能问题还是很多的,要掌握网络分析技能。
⑥ 页面渲染是DOM(文档对象模型,Document Object Model)对象的构建过程,了解渲染过程有助于定位分析前端性能问题。
可以看到,与全栈开发一样,性能测试要掌握的东西很广泛。要从前端测试到后端,不仅需要了解开发(分析和定位开发问题),还要了解运维(部署、执行负载时监控性能指标,从指标中找出风险与问题),更要了解业务,设计合适的压测场景,制作合理的测试数据。移动互联网产品种类多,包含的技术丰富,因此性能测试的技术面要求很宽。全栈性能测试就是要利用多种跨领域的知识,深入分析和发现移动互联网产品的问题,解决问题,为系统保驾护航。
下面我们结合当前互联网技术栈来探讨一下如何开展全栈性能测试,以及从事全栈性能测试的人员需要具备哪些技术能力。
“我们想做一下性能测试看一下系统有没有性能问题。”
“我们想测试一下系统能承载的最大用户数。”
“我们想测试一下系统能支持多少并发用户。”
做过性能测试的读者对上面3句话应该是耳熟能详。
抛开性能需求不谈,性能测试的确是要解决最大用户数(能支持的最大并发用户数)的问题。它抽象出了在一定场景下系统要满足的刚性需求,最大用户数反映到性能测试上就是系统的最大处理能力,只不过“一定场景”这个前提不清晰而已。
性能测试是一项综合性工作,致力于暴露性能问题,评估系统性能变化趋势。性能测试工作实质上是通过程序或者工具模拟大量用户操作来验证系统承载能力,找出潜在的性能问题,分析并解决这些问题;找出系统性能变化趋势,为后续的系统扩展提供参考。这里我们提到的“性能变化趋势”“系统承载能力”,它们怎么与最大用户数联系在一起呢?
以医院场景为例,医院的挂号窗口是相当忙碌的(尤其是三甲名院),那医院要开多少窗口才合适呢?(挂号这个业务的处理能力有多大?)此时患者是用户,不管用户有多少,医院的“挂号能力”(比如一分钟可以挂多少个号)决定了有多少人可以挂号。而医生每天能看多少病人决定了挂号量,挂号量决定挂号窗口每天只能放出多少号,所以即使挂号窗口的“挂号能力”很强,其处理能力也是受限的,挂号窗口要赶在患者看医生前挂完号即可。考虑到患者还要缴纳医药费的流量,我们简单把这个流量与挂号的流量对等。假设当值医生有100名,上午有效工作时间4小时,每位患者平均5分钟,那么医生效率是48人/医生/上午,我们用表1-1来统计一下。
表1-1 医院流量分析
类别 |
速度 |
工作量 |
时间 |
100位医生 |
挂号 |
需要 |
---|---|---|---|---|---|---|
挂号 |
30秒/人 |
48人 |
24分钟 |
4 800人 |
40小时 |
10 |
看诊 |
5分/人 |
48人/医生 |
240分钟 |
4 800人 |
400小时 |
|
缴费 |
30秒/人 |
48人 |
24分钟 |
4 800人 |
40小时 |
10 |
挂号与缴费总耗时80小时,约开20个窗口即可以在上午完成4 800人的挂号及缴费工作。如果这些窗口提前半小时开始挂号(工作时间变成4.5小时,其他条件不变),则需要17个窗口来完成挂号及缴费工作。排除网上挂号的(很多医生的号只能网上预约到)和自助机器上挂号的情况,也许10个窗口就够用了。因此可以在一楼开放10个窗口,在门诊楼其他楼层分别设置缴费窗口,方便患者,提高缴费效率。
本例中4 800人是医院的最大处理能力(系统承载能力),比这再多的用户超出了医院处理能力,可以拒之。这和线上系统超载了,请求也可以拒之是一样的道理。那如何提高看诊量呢?当然是提高医生看诊效率,利用医生的每一分钟;增加医生是最直接的解决办法,就好像在系统上增加机器一样。
那“性能变化趋势”呢?试想医院起初也不知道每年或每天的患者流量,随着医院的运营,历史的流量是能够统计出来的,这些数据反映了医院服务能力的“性能变化趋势”。基于这些数据就能够帮助决策,到底要开多少个窗口?哪个时段多开一些窗口?哪个时段关闭一些窗口?哪个季节患者流量大?要增加多少个医生?增加哪个类别的医生?医院要不要扩建?
说到“性能变化趋势”,我们看一下图1-2所示的性能变化曲线。
图1-2 性能变化曲线
图1-2中标记了4个点,x轴代表负载的增加,y轴代表吞吐量(TPS)及响应时间(RT)的增加。
随着负载的增加,响应时间与吞吐量线性增长,到达临界点(标记为3)时,吞吐量不再增加,继续增加负载会导致过载(比如我们在计算机上开启的软件过多导致系统卡死),吞吐量会受到拖累而减小,响应时间可能陡增(标记为4)。此时标记3代表了系统的最大处理能力。如果标记3的处理能力不能满足要求,那被测试的系统性能就堪忧了,需要进行性能诊断和优化。
有时,我们会要求响应时间要小于一个标准,比如请求某一个页面需要响应时间控制在3秒之内,时间长了用户体验差。假设图1-2中标记1、2、3的响应时间都不满足要求,即使吞吐量达到要求,我们也需要想办法缩短响应时间。再次假设在标记2处响应时间与吞吐量都满足性能要求,那么说明性能良好,而且性能还有提升空间,标记3才是系统性能的极限,标记4是系统性能“强弩之末”。
因此,我们在讨论性能时,至少要从系统响应时间与吞吐量两个维度来看是否满足性能要求;另外对于主机的资源(CPU、内存、磁盘、网络等)使用率也需要关注,太低则浪费,太高则危险。正如我们不会让发动机一直运行在极速情况下一样,也不会让计算机一直处在峰值处理能力状态,以延长机器的使用寿命及减少故障的发生。
图1-2这样的性能曲线诠释了软件的性能变化趋势。当取得软件的性能曲线后,我们在运营系统过程中就能够做到心中有数,知道什么时候要扩展,什么时候可以减少机器资源(比如在云上做自动伸缩)。当前,系统部署到云正在取代部署到物理机,而云服务商多数都是互联网企业。为什么会是它们呢?一个重要原因是,它们的物理主机很多,机器多是为了应付业务“暴涨”的场景,比如双11、6·18、春节抢红包等场景;而它们的业务量又不是一直都在满负荷运行,闲时的机器资源不利用就是浪费,所以把物理机器抽象成云来提供给第三方用户。
生产企业使用流水线来提高生产率,做性能测试也有流程。我们基于经验总结,参照项目管理实践来裁剪性能测试流程,图1-3所示是性能测试常规流程。
图1-3 性能测试常规流程
(1)学习业务:通过查看文档,并咨询提出测试需求的人员,手工操作系统来了解系统功能。
(2)分析需求:分析系统非功能需求,圈定性能测试的范围,了解系统性能指标。比如用户规模有多大,用户需要哪些业务功能,产生的业务量有多大,这些业务操作的时间分布如何,系统的部署结构怎样,部署资源有多大等。测试需求获取的途径主要有需求文档、业务分析人员,包括但不限于产品经理、项目经理等(在敏捷开发过程下,最直接的途径是从项目的负责人或者产品经理处获取相关需求信息)。
(3)工作评估:分解工作量,评估工作量,计划资源投入(需要多少个人,多少个工作日来完成性能测试工作)。
(4)设计模型:圈定性能测试范围后,把业务模型映射成测试模型。
什么是测试模型呢?比如一个支付系统需要与银行的系统进行交互(充值或者提现),由于银行不能够提供支持,我们会开发程序来代替银行系统功能(这就是挡板程序、Mock程序),保证此功能的性能测试能够开展,这个过程就是设计测试模型。通俗点说就是把测试需求落实,业务可测,可大规模使用负载程序去模拟用户操作,具有可操作性、可验证性;并根据不同的测试目的组合成不同的测试场景。
(5)编写计划:计划测试工作,在文档中明确列出测试范围、人力投入、持续时间、工作内容、风险评估、风险应对策略等。
(6)开发脚本:录制或者编写性能测试脚本(现在很多被测系统都是无法录制脚本的,我们需要手工开发脚本),开发测试挡板程序和测试程序等。有时候如果没有第三方工具可用,甚至需要开发测试程序或者工具。
(7)准备测试环境:准备性能测试环境包括服务器与负载机两部分,服务器是被测系统的运行平台(包括硬件与软件),负载机是我们用来产生负载的机器,用来安装负载工具,运行测试脚本。
(8)准备测试数据:根据数据模型来准备被测系统的主数据与业务数据(主数据是保证业务能够运行畅通的基础,比如菜单、用户等数据;业务数据是运行业务产生的数据,比如订单;订单出库需要库存数据,库存数据也是业务数据)。我们知道数据量变会引起性能的变化,在测试的时候往往要准备一些存量/历史业务数据,这些数据需要考虑数量与分布。
(9)执行测试:执行测试是性能测试成败的关键,同样的脚本,不同执行人员得出的结果可能差异较大。这些差异主要体现在场景设计与测试执行上。
(10)缺陷管理:对性能测试过程中发现的缺陷进行管理。比如使用Jira、ALM等工具进行缺陷记录,跟踪缺陷状态,统计分析缺陷类别、原因;并及时反馈给开发团队,以此为鉴,避免或者少犯同类错误。
(11)性能分析:性能分析指对性能测试过程中暴露出来的问题进行分析,找出原因。比如通过堆分析找出内存溢出问题。
(12)性能调优:性能调优指性能测试工程师与开发工程师一起来解决性能问题。性能测试工程师监控到异常指标,分析定位到程序,开发工程师对程序进行优化。
(13)评审(准出检查):对性能报告中的内容进行评审,确认问题、评估上线风险。有些系统虽然测试结果不理想,但基于成本及时间的考虑也会在评审会议中通过从而上线。
(14)编写测试报告,汇报工作:测试报告是测试工作的重要交付件,对测试结果进行记录总结,主要包括常见的性能指标说明(TPS、RT、CPU Using……)、发现的问题等。
性能测试主要交付件有:
如果性能测试执行过程比较长,换句话说性能测试过程中性能问题比较多,经过了多轮的性能调优,需要执行多次回归测试,那么在这个过程中需要提交阶段性测试报告。
性能测试不仅仅是录制脚本或者编写测试程序(测试工具),对基本的性能理论、执行策略必须要了解。同样的脚本,新手与行家分别执行,测试结果也许会大相径庭。实际上我们需要对系统进行一系列复杂的需求分析,制定完善的测试计划,设计出贴近实际用户使用场景的用例,压测时更是要产生有效负载,经过反复测试实验,找到性能问题。
图1-4所示为性能测试常用的技术栈(包括但不限于)。
图1-4 性能测试常用的技术栈
性能测试理论用来指导我们开展性能测试,指导我们要得到什么结果,让我们了解测试过程是否可靠,测试结果是否具备可参考性。
对于性能测试理论,我们主要关注下面几点:
(1)测试需求分析要能够准确挖掘出性能需求,圈定测试范围,并有明确的性能指标;
(2)测试模型要能够尽量真实地反映系统的实际使用情况;
(3)测试环境尽量对标实际(避免使用云主机,避免使用虚机);
(4)测试数据在量与结构上尽量与实际对标;
(5)测试场景要考虑业务关联,尽量还原实际使用情况;
(6)测试监控尽可能少地影响系统性能;
(7)测试执行时测试结果要趋于稳定。
以上性能测试理论会在其他章节讲解综合实战时结合实例详细讲解(请参照第7章)。
系统(产品)的多样性决定了测试程序的多样性,不是所有的系统都有工具可以帮助进行测试的,有时候我们需要自己动手开发测试程序。比如RPC作为通信方式时,针对此类接口的测试就很少有工具支持(现在已经有一些专用的,如Dubbo),通常需要自己开发。另外,我们在做性能诊断分析时,不可避免地会面对代码,没有开发技能,诊断分析问题谈何容易?所以具备开发能力会更从容地解决问题。当然不具备开发能力也不代表一定不会诊断分析问题,利用工具、遵循理论,也是可以找到问题所在的;长期的积累,也会具备调优能力。
合适的性能测试工具能够帮助提高测试效率,让我们腾出时间专注于问题分析。主流的性能测试工具有LoadRunner与JMeter(其他还有很多,比如Ab、Grinder等)。当然,工具也不能解决所有问题,有时候还是需要自己编写程序来实现测试脚本。很多初学者认为这两个工具只能用来做性能测试,其实能做性能测试的工具也可以做功能自动化测试。不是非得Selenium、WebDriver才能做自动化测试。
如何选择工具呢?
首先我们要明白负载工具是帮助我们来模拟负载的。对于性能测试来说,工具并不是核心,找出、分析、评估性能问题才是核心,这些是主观因素。工具是客观因素,自然要降低其对结果的影响,因此选择工具时,我们要考虑几个方面。
(1)专业、稳定、高效,比如工业级性能负载工具LoadRunner。
(2)简单、易上手,在测试脚本上不用花太多时间。
(3)有技术支持,文档完善,不用在疑难问题上花费时间,可集中精力在性能分析上。
(4)要考虑投入产出比,比如我们可以选择免费开源的JMeter。当然,有时候自研或者使用开源不一定比商业工具更省钱,因为要做技术上的投资、时间上的投资。
常见的性能测试工具:
(1)HP公司的LoadRunner;
(2)Apache JMeter(开源);
(3)Grinder(开源);
(4)CompuWare公司的QALoad;
(5)Microsoft公司的WAS;
(6)RadView公司的WebLoad;
(7)IBM公司的RPT;
(8)OPENSTA;
(9)BAT(百度、阿里巴巴和腾讯)等企业的在线压力测试平台。
下面对选择自研及开源工具与商业工具做一下比较,如表1-2所示。
表1-2 自研及开源工具与商业工具
自研/开源 |
商 业 工 具 |
---|---|
能够开发出最适合应用的测试工具 |
依赖于工具本身提供的特性,较难扩展 |
易于学习和使用 |
依赖于工具的易用性和所提供的文档 |
工具的稳定性和可靠性不足 |
稳定性和可靠性有一定保证 |
可形成团队特有的测试工具体系 |
很难与其他产品集成 |
成本低,技术要求高 |
短期购买成本高,技术要求低 |
总之,我们要认清性能测试的核心是性能分析,重要的是思想和实现方式,不在于工具。大家要本着简单、稳定、专业、高效、省钱的原则来选择工具。
业务及业务量决定了系统的复杂度,系统的复杂度会影响系统架构,系统架构决定了开发模式。现在流行微服务,流行前后端分离的分层开发,性能测试自然也需要迎合开发方式的变化,所以我们现在的性能分析诊断也需要分层。下面我们来看看每一层要注意些什么。
目前的开发形式多采用前后端分离的方式,一套后端系统处理多套前端请求;用户通过手机里的App(Hybrid应用、H5应用、Native应用)和PC中的浏览器来访问系统。JavaScript的运用让前端技术发展迅速,App的运用让前端可以存储、处理更多业务。随着功能的增多自然会带来性能问题,前端的性能问题越来越成为广泛的性能问题。幸运的是前端应用性能的监控工具也有不少。
不管我们的程序如何“高大上”,也不管用什么语言开发程序,程序运行时最终还是要依赖服务器硬件。服务器硬件是性能之本,所有性能都会反映到硬件指标上,我们想要分析性能,少不了服务器知识。测试人员要对服务器“几大件”,如CPU、存储、内存、网络的性能指标及监控方法都需要熟练掌握。管理这些硬件的操作系统原理、性能配置参数也需要掌握。要掌握这部分需要学习很多运维和开发知识。
了解操作系统及其内核对于系统分析至关重要。作为性能测试工程师,我们需要对系统做分析:系统调用是如何执行的、CPU是如何调度线程的、有限大小的内存是如何影响性能的、文件系统是如何处理IO的,这些都是我们判断系统瓶颈的依据和线索。
对于操作系统,我们主要掌握Linux与Windows Server(其他如AIX、Solaris主要应用在传统的大型国企、金融企业,专业性强,由供应商提供商业服务)。
(1)Linux。
Linux是开源的类UNIX操作系统,Linux继承了UNIX以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。越来越多的企业用这个系统作为服务器的操作系统,因此作为性能测试从业者来说,它是必须掌握的操作系统之一。
目前Linux/UNIX的分支很多,比较普及的有CentOS、Ubuntu、RedHat、AIX、Solaris等。
(2)Windows Server。
Windows Server是Microsoft Windows Server System(WSS)的核心,是服务器操作系统。目前使用此系统比较多的是中小型公司。Windows Server的资源监视器功能完善,图形界面友好,使用非常方便。用户只需要了解各项指标的意义,就可以方便、快捷地对运行的程序进行诊断分析。
主流的中间件非Tomcat莫属了。Tomcat作为一个载体,帮助我们实现了通信及作业功能,提供了一套规范,我们只需要遵循规范,开发出实现业务逻辑的代码,就可以发布成系统。它为我们省掉了基础通信功能和多线程程序的开发,让我们可以专注业务逻辑的实现。Tomcat在不同场景下也会遇到性能瓶颈,熟练使用Tomcat对于性能测试工程师解决性能问题也是必要的。
Tomcat有一些性能指标用来反映服务的“健康状况”,如活动线程数、JVM内存分配、垃圾回收情况、数据库连接池使用情况等。
中间件不只有Tomcat这样的Java Servlet容器,类似Tomcat支持Java程序的中间件还有Jetty、Weblogic、WebSphere、Jboss等。
现在分布式系统架构是主流,系统间的数据通信(同步)很多通过消息中间件来解决,如ActiveMQ、Kafka、Rabbitmq等,这些中间件的配置使用对性能也会产生显著影响。
数据的持久化有结构数据、非结构数据、块数据、对象数据,存储时对应不同类型的存储产品。比如关系型数据库(MySQL、Oracle等),非关系型数据库(Redis、HBase等),分布式存储(hdfs、ceph等),这些都属于IO操作。IO操作一直都是性能“重灾区”,因为不管什么类型的存储,终究是把数据存到存储介质上。存储介质广泛使用的是固态硬盘(SSD)和机械硬盘。机械硬盘是物理读写(IO),其的读写速度相对固态硬盘相差巨大。我们启动计算机时,如果操作系统不在固态硬盘上,启动用时至少30多秒;而操作系统在固态硬盘上,启动时间是几秒。图1-5所示是三星固态硬盘官方公布的主要读写性能指标,图1-6所示是希捷机械硬盘读写性能指标。
图1-5 三星固态硬盘读写性能指标
图1-6 希捷机械硬盘读写性能指标
我们可以通过监听存储介质的性能指标来诊断程序在IO上的耗时,并针对性地优化对存储的访问(比如减少请求次数来减少IO)。存储介质的性能是一定的,我们需要对依赖它的持久化产品做文章,如MySQL数据库的慢查询,Redis存储的键值长度等。所有这些都需要我们去监控,通过监控推导出问题所在。
作为IT部门的一员,不可避免地要和代码打交道,了解编程知识既能加深对性能测试的理解,还能提高和程序员沟通效率。更重要的是,做自动化测试、单元测试、性能测试、安全测试都离不开对代码的理解。所以我们要掌握一些使用率高的编程语言和脚本语言,如Java、Python等。
代码问题通常集中在事务、多线程、通信、存储及算法方面。测试人员可以不必去写一段优秀的代码,但要能够定位问题到代码段。
高性能的系统架构与普通系统架构也不一样。性能优化或者性能规划要依照系统的用户规模来设计,了解架构有助于快速判断系统性能风险,有针对性地进行性能压测实验,提出合适的解决方案。
中间件的性能指标反映了系统的运行状况,我们要能够通过这些指标推导出系统的问题所在。有些可以通过调整中间件的配置来改善系统性能,比如用户请求过多,可以适当增大线程池;当JVM内存回收,特别是Full GC过于频繁时,我们就要分析到底是哪些程序导致了大量的Heap(堆)内存申请;当CPU过于繁忙时,我们会去分析哪个线程占用了大量CPU资源,通过线程信息定位到程序。这些都是常见的分析方法,也容易掌握,掌握这些分析方法能够解决80%以上的性能定位问题。
操作系统统筹管理计算机硬件资源,针对不同业务,不同场景也会有一些可以优化的参数。我们首先要知道操作系统的限制,这需要从监控的指标中推导。常见调优方法有:文件句柄数设置、网络参数优化、亲和性设置、缓存设置等。
系统中流转的数据离不开持久化,持久化需要数据库。数据在数据库中的存储结构和搜索方式直接影响性能,大多数的性能调优都集中在数据库的存储及查询上。学好数据库的理论知识,学会分析SQL的执行计划是一种基础技能。现在很多系统都用Redis来做热点数据的存储,在测试时对于影响Redis性能的因素要了解。比如Key-Value存储时Value过长,性能就会急剧下降,因为网络传输时数据包的MTU(最大数据包大小,Maximum Transmission Unit,这也是操作系统的知识点)通常是1 500字节,大的数据包需要在网络中多次传输,当然效率低下。如何优化数据库呢?最直接的想法是减少Value长度,分析为什么Value这么长,能否减少或者压缩,之后才是从数据库的业务逻辑上去考虑优化。
性能测试是一个反反复复的过程,发布后执行压测,分析问题、找到问题、修改问题,再发布、再执行压测。使用持续集成工具有利于提高工作效率。当下通常用Git/SVN来管理代码版本,使用Jenkins来做持续集成,同时我们也可以利用Jenkins来自动化性能压测过程。
云计算已成为主流技术,我们的服务会部署在云环境,因此对于云环境的了解自然不能落下。我们在云环境用虚机或容器(如Docker)技术来发布程序,这些对于性能的影响也是我们要考虑的问题,熟悉虚机与容器是自然的事。Docker容器是当前市场占有量最大的容器产品之一,对主流产品的学习也可以帮我们扩大知识面;Kubernetes已经成为容器编排产品的集大成者。
(1)并发(Concurrency)/并行(Parallelism):如果CPU是8核的,理论上同一时刻CPU可以同时处理8个任务。当有8个请求同时进来时,这些任务被CPU的8核分别处理,它们都拥有CPU资源并不相互干扰,此时CPU是在并行地处理任务。如果是单核CPU,同时有8个请求进来时,请求只能排队被CPU处理,此时8个请求是并发的,因为它们同一时刻进来,而处理是一个一个的。所以并发是针对一个对象(单核CPU)发生多个事件(请求),并行是多个对象(多个CPU核)同时处理多个事件(请求)。同理,当请求多于8个,那么也可以在多核CPU前形成并发的情况。我们常听到的“并发用户数”并不是像本例中的8个请求,比如一个系统有200个用户,即使他们都在线,也不能代表他们都操作了业务,用户可能仅仅是上去看一下信息然后挂机,所以通常听到的“并发用户数”并不能作为真实的性能测试需求,而应该以产生的业务量(交易量/请求数)为性能需求。
(2)负载:模拟业务操作对服务器造成压力的过程,比如模拟100个用户进行订单提交。负载的产生受数据的影响,我们常说量变引起质变,比如查询100条与查询100万条数据的响应时间很可能有差异。
(3)性能测试(Performance Testing):模拟用户负载来测试在负载情况下,系统的响应时间、吞吐量等指标是否满足性能要求。
(4)负载测试(Load Testing):在一定软硬件环境下,通过不断加大负载(不同虚拟用户数)来确定在满足性能指标情况下的承载极限。简单地说,它可以帮助我们对系统进行定容定量,找出系统性能的拐点,给出生产环境规划的建议。这里的性能指标包括TPS(每秒事务数)、RT(事务平均响应时间)、CPU Using(CPU利用率)、Mem Using(内存使用率)等软硬件指标。从操作层面上来说,负载测试也是一种性能测试手段,比如配置测试就需要变换不同的负载来进行测试。
(5)配置测试(Configuration Testing):为了合理地调配资源,提高系统运行效率,通过测试手段来获取、验证、调整配置信息的过程。通过这个过程我们可以收集到不同配置反映的不同性能,从而为设备选择、设备配置提供参考。
(6)压力/强度测试(Stress Testing):在一定软硬件环境下,通过高负载的手段使服务器资源(强调服务器资源,硬件资源)处于极限状态,测试系统在极限状态下长时间运行是否稳定,确定是否稳定的指标包括TPS、RT、CPU使用率、Mem使用率等。
(7)稳定性测试(Endurance Testing):在一定软硬件环境下,长时间运行一定负载,确定系统在满足性能指标的前提下是否运行稳定。与上面的压力/强度测试区别在于,稳定性测试负载并不强调是在极限状态下,着重的是满足性能要求的情况下系统的稳定性,比如响应时间是否稳定、TPS是否稳定、主机是否稳定。一般我们会在满足性能要求的负载情况下加大1.5~2倍的负载量进行测试。
(8)TPS:每秒完成的事务数,有时用QPS(每秒查询数)来代替,通常指每秒成功的事务数,这是性能测试中重要的综合性性能指标。一个事务是一个业务度量单位,有时一个事务会包括多个子操作,但为了方便统计,我们会把这些子操作计为一个事务。比如一笔电子支付操作,在后台系统中可能会经历会员系统、账务系统、支付系统、会计系统、银行网关等,但对于用户来说只想知道整笔支付花费了多长时间。
(9)RT/ART(Response Time/Average Response Time):响应时间/平均响应时间,指一个事务花费多长时间完成(多长时间响应客户请求),为了使这个响应时间更具代表性,会统计更多的响应时间然后取平均值,即得到了事务平均响应时间(ART),通常我们说的RT是代指平均响应时间。
(10)PV(Page View):每秒用户访问页面的次数,此参数用来分析平均每秒有多少用户访问页面。
(11)Vuser虚拟用户(Virtual User):模拟真实业务逻辑步骤的虚拟用户,虚拟用户模拟的操作步骤都被记录在虚拟用户脚本里。Vuser脚本用于描述Vuser在场景中执行的操作。
(12)场景(Scenario):性能测试过程中为了模拟真实用户的业务处理过程,在测试工具中构建的基于事务、脚本、虚拟用户、运行设置、运行计划、监控、分析等一系列动作的集合,称之为性能测试场景。此场景中包含了待执行脚本、脚本组、并发用户数、负载生成器、测试目标、测试执行时的配置条件等。简单地说,就是把若干个业务的性能测试脚本组织成一个执行单元,对执行单元进行一揽子的配置来保证测试的有效执行。比如负载测试时,我们可以设置一种图1-7所示的阶梯形负载增长场景。
图1-7 阶梯形负载增长场景
(13)思考时间(Think Time):模拟正式用户在实际操作时的停顿间隔时间。从业务的角度来讲,思考时间指的是用户在进行操作时,每个请求之间的间隔时间;在测试脚本中,思考时间体现为脚本中两个请求语句之间的间隔时间。
(14)标准差(Std. Deviation):该标准差根据数理统计的概念得来,标准差越小,说明波动越小,系统越稳定;反之,标准差越大,说明波动越大,系统越不稳定。常见的标准差包括响应时间标准差、TPS标准差、Running Vuser标准差、Load标准差、CPU资源利用率标准差等。
(1)本书中不做特殊说明的话,JDK 7和JDK 1.7都是指Oracle JDK 7的版本,类似JDK 8与JDK 1.8也指同一版本。
(2)本书中JMeter Sampler与“取样器”是同一概念。
(3)本书说到的IO与I/O同一意思,都是泛指输入输出操作,比如文件读写、网络包的传输等。
(4)本书涉及的脚本、配置及文档,都可以从作者公众号(二维码如下)获取,方便读者学习。
青山如许
本章讲解了全栈性能测试的基本理论,相信大家对全栈性能测试已经有了一个初步认识。性能测试工作是一个综合学科。测试人员对技术掌握程度要求高、知识面要求广,也要具备一定沟通能力。性能测试的工作过程中要注意的关键点也比较多。首先,要做好性能需求分析,不充分的性能需求分析会直接导致性能测试工作失败;其次,要做好用例及场景设计,尽可能复现实际负载,这样的执行工作才是可信赖的、可参考的;最后,执行过程中要做好性能监控工作,为分析问题提供数据支撑。