全栈性能测试详解
创始人
2024-04-03 18:06:34
0

一、全栈性能测试概述

1、全栈工程师

全栈工程师能够完成产品设计,技术选型,架构落地;可以开发前端和后台程序,并部署到生产环境。一人多用,省成本,完全没有多人配合时的工作推诿和沟通不畅等情况发生,这是创业公司找工程师时,全栈工程师是首选的原因。

大互联网公司的系统平台更复杂,需要更多的角色通力协作完成任务。那是不是全栈工程师在大企业就没有存在的必要了呢?当然有必要。大企业需要从全局考虑来做顶层设计,对于做顶层设计的人来说知识面宽尤为重要。这个人可以不是每一个细分领域的专家,但能够与某些领域专家交流畅顺,能够理会对方意思,尽可能地从全局考虑项目的优化设计,这类人是全栈工程师的典型代表。一位互联网全栈工程师需

要掌握包括但不限于如下技术:

  • 前端(简单列举):HTML、H5、CSS、JavaScript、React、Vue、Angular、NodeJS、WebSocket、HTTP等。
  • 后台:中间件(Tomcat、Jetty)、消息中间件(Kafka、RabbitMQ、RocketMQ等)、开发框架(Springboot/Cloud、Dubbo等,ORM:Hibernate、MyBatis、Spring JPA等)。
  • 数据库:关系数据库(MySQL、Oracle等)、NoSQL数据库(Redis MongoDB HBase等)。
  • 集成工具:Git、Gitlab、CVS、Jenkins、Sonar、Maven等。
  • 容器及编排工具:Docker、Kubernetes等。
  • 监控工具:Prometheus、Skywalking、Zabbix等。
  • 操作系统:Linux系列(CentOS、Fedora、Debian、Ubuntu之一或者多种)。

如果你是从事大数据方面的开发,还需要掌握的技术如下:

  • Hadoop、Spark、Storm、Flink、Tensorflow、Lucene、Solr、ElasticSearc、Hive/Impala等。当然,你还要熟悉各种算法、统计方法,数学等。

2、全栈性能测试引入

网络平台的崛起,带来巨大的流量,也催生技术的革新。高度集中和融合的系统,结构复杂,技术栈庞大,使测试变得困难。在定位、分析问题时往往会跨技术栈,测试人员靠单一技能并不能较好地完成测试工作。与全栈开发一样,全能型(跨技术栈)测试人才变得抢手,也自然催生出全栈测试概念。

以我们熟悉的支付系统来说,我们在手机上轻轻点一下就把钱支付的看似简单的操作,在其工作流程的背后可能要经过十几个系统,涉及商家、平台、支付企业、银行等多个角色。对这类系统测试时链路长,尤其是做链条测试时,每个系统都要检查,第三方系统还要沟通配合。如对接银行系统的过程中,一般在沟通上最耗时,这也是测试工程师最无力把控的部分。

例如支付企业,整个支付系统加上金融产品,大大小小共90多个子系统,测试团队部署新版本时都感到头痛,主要风险在版本管理及配置管理方面,特别是进行敏捷开发时,面对多个测试环境(开发环境、集成环境、测试环境、QA验证、模拟环境、生产环境)的情况下,负责功能测试的同事苦不堪言。测试工作除了考验测试人员的业务、技术,还考验测试人员的心态。这个时候能够从容不迫、心静如水的往往都是技术过硬的人。

技术过硬的人已经熟悉了技术栈、业务流向、测试环境,能够有条不紊地开展工作。所以这些技术过硬的人往往都是测试团队的主力。大数据分析、AI、云计算、Devops是当前系统应用的主流技术,这方面的测试对测试人员的技术要求更高。

以大数据分析为例,测试数据的制作就是一门学问。测试人员最好能够了解实现功能的算法,设计有针对性的数据。

全栈概念很广,测试人员可以选择一些点突破。如做云计算的测试,要了解虚拟化、容器、虚拟网络、服务编排工具等;做AI测试要了解AI的算法、训练模型,力争储备更多的知识。

3、全栈性能测试概要

在软件行业、互联网行业,软件性能是企业的竞争力。良好的性能才能保证优质的用户体验,谁也不想忍受“蜗牛般”的应用加载,这样的应用会丢失用户。技术在发展,用户对性能的要求在提高,测试人员面对不断更新的技术,庞大的技术栈,性能测试的技术储备也要拓宽。

下面看一下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)对象的构建过程,了解渲染过程有助于定位分析前端性能问题。可以看到,与全栈开发一样,性能测试要掌握的东西很广泛。要从
前端测试到后端,不仅需要了解开发(分析和定位开发问题),还要了解运维(部署、执行负载时监控性能指标,从指标中找出风险与问题),更要了解业务,设计合适的压测场景,制作合理的测试数据。移动互联网产品种类多,包含的技术丰富,因此性能测试的技术面要求很宽。全栈性能测试就是要利用多种跨领域的知识,深入分析和发现移动互联网产品的问题,解决问题,为系统保驾护航。 

4、全栈性能测试需要具备哪些技术能力

1. 性能测试要解决的问题

“我们想做一下性能测试看一下系统有没有性能问题。”

“我们想测试一下系统能承载的最大用户数。”

“我们想测试一下系统能支持多少并发用户。”

做过性能测试的朋友对上面3句话应该是耳熟能详。

抛开性能需求不谈,性能测试的确是要解决最大用户数(能支持的最大并发用户数)的问题。它抽象出了在一定场景下系统要满足的刚性需求,最大用户数反映到性能测试上就是系统的最大处理能力,只不过“一定场景”这个前提不清晰而已。

性能测试是一项综合性工作,致力于暴露性能问题,评估系统性能变化趋势。性能测试工作实质上是通过程序或者工具模拟大量用户操作来验证系统承载能力,找出潜在的性能问题,分析并解决这些问题;找出系统性能变化趋势,为后续的系统扩展提供参考。这里我们提到的“性能变化趋势”“系统承载能力”,它们怎么与最大用户数联系在一起呢?

以医院场景为例,医院的挂号窗口是相当忙碌的(尤其是三甲名院),那医院要开多少窗口才合适呢?(挂号这个业务的处理能力有多大?)此时患者是用户,不管用户有多少,医院的“挂号能力”(比如一分钟可以挂多少个号)决定了有多少人可以挂号。而医生每天能看多少病人决定了挂号量,挂号量决定挂号窗口每天只能放出多少号,所以即使挂号窗口的“挂号能力”很强,其处理能力也是受限的,挂号窗口要赶在患者看医生前挂完号即可。考虑到患者还要缴纳医药费的流量,我们
简单把这个流量与挂号的流量对等。假设当值医生有100名,上午有效工作时间4小时,每位患者平均5分钟,那么医生效率是48人/医生/上午,我们用表来统计一下。

类别速度工作量时间100位医生看诊/上午挂号总耗时需要窗口数
挂号39秒/人48人24分钟4800人40小时10
看诊50分/人48人/医生240分钟4800人400小时
缴费30秒/人48人24分钟4800人40小时10

挂号与缴费总耗时80小时,约开20个窗口即可以在上午完成4 800人的挂号及缴费工作。如果这些窗口提前半小时开始挂号(工作时间变成4.5小时,其他条件不变),则需要17个窗口来完成挂号及缴费工作。

排除网上挂号的(很多医生的号只能网上预约到)和自助机器上挂号的情况,也许10个窗口就够用了。因此可以在一楼开放10个窗口,在门诊楼其他楼层分别设置缴费窗口,方便患者,提高缴费效率。

本例中4 800人是医院的最大处理能力(系统承载能力),比这再多的用户超出了医院处理能力,可以拒之。这和线上系统超载了,请求也可以拒之是一样的道理。那如何提高看诊量呢?当然是提高医生看诊效率,利用医生的每一分钟;增加医生是最直接的解决办法,就好像在系统上增加机器一样。

那“性能变化趋势”呢?试想医院起初也不知道每年或每天的患者流量,随着医院的运营,历史的流量是能够统计出来的,这些数据反映了医院服务能力的“性能变化趋势”。基于这些数据就能够帮助决策,到底要开多少个窗口?哪个时段多开一些窗口?哪个时段关闭一些窗口?哪个季节患者流量大?要增加多少个医生?增加哪个类别的医生?医院要不要扩建?

说到“性能变化趋势”,我们看一下图所示的性能变化曲线。

上图中标记了4个点,x轴代表负载的增加,y轴代表吞吐量(TPS)及响应时间(RT)的增加。

随着负载的增加,响应时间与吞吐量线性增长,到达临界点(标记为3)时,吞吐量不再增加,继续增加负载会导致过载(比如我们在计算机上开启的软件过多导致系统卡死),吞吐量会受到拖累而减小,响应时间可能陡增(标记为4)。此时标记3代表了系统的最大处理能力。

如果标记3的处理能力不能满足要求,那被测试的系统性能就堪忧了,需要进行性能诊断和优化。
有时,我们会要求响应时间要小于一个标准,比如请求某一个页面需要响应时间控制在3秒之内,时间长了用户体验差。

假设图中标记1、2、3的响应时间都不满足要求,即使吞吐量达到要求,我们也需要想办法缩短响应时间。再次假设在标记2处响应时间与吞吐量都满足性能要求,那么说明性能良好,而且性能还有提升空间,标记3才是系统性能的极限,标记4是系统性能“强弩之末”。

因此,我们在讨论性能时,至少要从系统响应时间与吞吐量两个维度来看是否满足性能要求;另外对于主机的资源(CPU、内存、磁盘、网络等)使用率也需要关注,太低则浪费,太高则危险。正如我们不会让发动机一直运行在极速情况下一样,也不会让计算机一直处在峰值处理能力状态,以延长机器的使用寿命及减少故障的发生。

上图这样的性能曲线诠释了软件的性能变化趋势。当取得软件的性能曲线后,我们在运营系统过程中就能够做到心中有数,知道什么时候要扩展,什么时候可以减少机器资源(比如在云上做自动伸缩)。当前,系统部署到云正在取代部署到物理机,而云服务商多数都是互联网企业。

为什么会是它们呢?一个重要原因是,它们的物理主机很多,机器多是为了应付业务“暴涨”的场景,比如双11、6·18、春节抢红包等场景;而它们的业务量又不是一直都在满负荷运行,闲时的机器资源不利用就是浪费,所以把物理机器抽象成云来提供给第三方用户。

2. 如何开展性能测试

生产企业使用流水线来提高生产率,做性能测试也有流程。我们基于经验总结,参照项目管理实践来裁剪性能测试流程,下图所示是性能测试常规流程。

(1)学习业务:通过查看文档,并咨询提出测试需求的人员,手工操作系统来了解系统功能。

(2)分析需求:分析系统非功能需求,圈定性能测试的范围,了解系统性能指标。比如用户规模有多大,用户需要哪些业务功能,产生的业务量有多大,这些业务操作的时间分布如何,系统的部署结构怎样,部署资源有多大等。测试需求获取的途径主要有需求文档、业务分析人员,包括但不限于产品经理、项目经理等(在敏捷开发过程下,最直接的途径是从项目的负责人或者产品经理处获取相关需求信息)。

(3)工作评估:分解工作量,评估工作量,计划资源投入(需要多少个人,多少个工作日来完成性能测试工作)。

(4)设计模型:圈定性能测试范围后,把业务模型映射成测试模型。什么是测试模型呢?比如一个支付系统需要与银行的系统进行交互(充值或者提现),由于银行不能够提供支持,我们会开发程序来代替银行系统功能(这就是挡板程序、Mock程序),保证此功能的性能测试能够开展,这个过程就是设计测试模型。通俗点说就是把测试需求落实,业务可测,可大规模使用负载程序去模拟用户操作,具有可操作性、可验证性;并根据不同的测试目的组合成不同的测试场景。

(5)编写计划:计划测试工作,在文档中明确列出测试范围、人力投入、持续时间、工作内容、风险评估、风险应对策略等。

(6)开发脚本:录制或者编写性能测试脚本(现在很多被测系统都是无法录制脚本的,我们需要手工开发脚本),开发测试挡板程序和测试程序等。有时候如果没有第三方工具可用,甚至需要开发测试程序或者工具。

(7)准备测试环境:准备性能测试环境包括服务器与负载机两部分,服务器是被测系统的运行平台(包括硬件与软件),负载机是我们用来产生负载的机器,用来安装负载工具,运行测试脚本。

(8)准备测试数据:根据数据模型来准备被测系统的主数据与业务数据(主数据是保证业务能够运行畅通的基础,比如菜单、用户等数据;业务数据是运行业务产生的数据,比如订单;订单出库需要库存数据,库存数据也是业务数据)。我们知道数据量变会引起性能的变化,在测试的时候往往要准备一些存量/历史业务数据,这些数据需要考虑数量与分布。

(9)执行测试:执行测试是性能测试成败的关键,同样的脚本,不同执行人员得出的结果可能差异较大。这些差异主要体现在场景设计与测试执行上。

(10)缺陷管理:对性能测试过程中发现的缺陷进行管理。比如使用Jira、ALM等工具进行缺陷记录,跟踪缺陷状态,统计分析缺陷类别、原因;并及时反馈给开发团队,以此为鉴,避免或者少犯同类错误。

(11)性能分析:性能分析指对性能测试过程中暴露出来的问题进行分析,找出原因。比如通过堆分析找出内存溢出问题。

(12)性能调优:性能调优指性能测试工程师与开发工程师一起来解决性能问题。性能测试工程师监控到异常指标,分析定位到程序,开发工程师对程序进行优化。

(13)评审(准出检查):对性能报告中的内容进行评审,确认问题、评估上线风险。有些系统虽然测试结果不理想,但基于成本及时间的考虑也会在评审会议中通过从而上线。

(14)编写测试报告,汇报工作:测试报告是测试工作的重要交付件,对测试结果进行记录总结,主要包括常见的性能指标说明(TPS、RT、CPU Using……)、发现的问题等。

性能测试主要交付件有:

  • 测试计划;
  • 测试脚本;
  • 测试程序;
  • 测试报告或者阶段性测试报告;

如果性能测试执行过程比较长,换句话说性能测试过程中性能问题比较多,经过了多轮的性能调优,需要执行多次回归测试,那么在这个过程中需要提交阶段性测试报告。

3. 全栈性能测试技术栈

性能测试不仅仅是录制脚本或者编写测试程序(测试工具),对基本的性能理论、执行策略必须要了解。同样的脚本,新手与行家分别执行,测试结果也许会大相径庭。实际上我们需要对系统进行一系列复杂的需求分析,制定完善的测试计划,设计出贴近实际用户使用场景的用例,压测时更是要产生有效负载,经过反复测试实验,找到性能问题。

下图所示为性能测试常用的技术栈(包括但不限于):

1) 性能测试理论

性能测试理论用来指导我们开展性能测试,指导我们要得到什么结果,让我们了解测试过程是否可靠,测试结果是否具备可参考性。

对于性能测试理论,我们主要关注下面几点:

  1. 测试需求分析要能够准确挖掘出性能需求,圈定测试范围,并有明确的性能指标;
  2. 测试模型要能够尽量真实地反映系统的实际使用情况;
  3. 测试环境尽量对标实际(避免使用云主机,避免使用虚机);
  4. 测试数据在量与结构上尽量与实际对标;
  5. 测试场景要考虑业务关联,尽量还原实际使用情况;
  6. 测试监控尽可能少地影响系统性能;
  7. 测试执行时测试结果要趋于稳定

2)测试开发技能

系统(产品)的多样性决定了测试程序的多样性,不是所有的系统都有工具可以帮助进行测试的,有时候我们需要自己动手开发测试程序。比如RPC作为通信方式时,针对此类接口的测试就很少有工具支持(现在已经有一些专用的,如Dubbo),通常需要自己开发。另外,我们在做性能诊断分析时,不可避免地会面对代码,没有开发技能,诊断分析问题谈何容易?所以具备开发能力会更从容地解决问题。

当然不具备开发能力也不代表一定不会诊断分析问题,利用工具、遵循理论,也是可以找到问题所在的;长期的积累,也会具备调优能力。

3)负载工具

合适的性能测试工具能够帮助提高测试效率,让我们腾出时间专注于问题分析。主流的性能测试工具有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(百度、阿里巴巴和腾讯)等企业的在线压力测试平台。

下面对选择自研及开源工具与商业工具做一下比较:

自研/开源 商业工具
能够开发出最适合应用的测试工具 依赖于工具本身提供的特性,较难扩展
易于学习和使用 依赖于工具的易用性和所提供的文档
工具的稳定性和可靠性不足 稳定性和可靠性有一定保证
可形成团队特有的测试工具体系 很难与其他产品集成
成本低,技术要求高 短期购买成本高,技术要求低

总之,我们要认清性能测试的核心是性能分析,重要的是思想和实现方式,不在于工具。大家要本着简单、稳定、专业、高效、省钱的原则来选择工具。

4)前端监听诊断

目前的开发形式多采用前后端分离的方式,一套后端系统处理多套前端请求;用户通过手机里的App(Hybrid应用、H5应用、Native应用)和PC中的浏览器来访问系统。JavaScript的运用让前端技术发展迅速,App的运用让前端可以存储、处理更多业务。随着功能的增多自然会带来性能问题,前端的性能问题越来越成为广泛的性能问题。幸运的是前端应用性能的监控工具也有不少。

5)服务器监听诊断

不管我们的程序如何“高大上”,也不管用什么语言开发程序,程序运行时最终还是要依赖服务器硬件。服务器硬件是性能之本,所有性能都会反映到硬件指标上,我们想要分析性能,少不了服务器知识。测试人员要对服务器“几大件”,如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的资源监视器功能完善,图形界面友好,使用非常方便。用户只需要了解各项指标的意义,就可以方便、快捷地对运行的程序进行诊断分析。

6)中间件监听诊断

主流的中间件非Tomcat莫属了。Tomcat作为一个载体,帮助我们实现了通信及作业功能,提供了一套规范,我们只需要遵循规范,开发出实现业务逻辑的代码,就可以发布成系统。它为我们省掉了基础通信功能和多线程程序的开发,让我们可以专注业务逻辑的实现。

Tomcat在不同场景下也会遇到性能瓶颈,熟练使用Tomcat对于性能测试工程师解决性能问题也是必要的。

Tomcat有一些性能指标用来反映服务的“健康状况”,如活动线程数、JVM内存分配、垃圾回收情况、数据库连接池使用情况等。

中间件不只有Tomcat这样的Java Servlet容器,类似Tomcat支持Java程序的中间件还有Jetty、Weblogic、WebSphere、Jboss等。

现在分布式系统架构是主流,系统间的数据通信(同步)很多通过消息中间件来解决,如ActiveMQ、Kafka、Rabbitmq等,这些中间件的配置使用对性能也会产生显著影响。

7)持久化产品监听

数据的持久化有结构数据、非结构数据、块数据、对象数据,存储时对应不同类型的存储产品。比如关系型数据库(MySQL、Oracle等),非关系型数据库(Redis、HBase等),分布式存储(hdfs、ceph等),这些都属于IO操作。

IO操作一直都是性能“重灾区”,因为不管什么类型的存储,终究是把数据存到存储介质上。存储介质广泛使用的是固态硬盘(SSD)和机械硬盘。机械硬盘是物理读写(IO),其的读写速度相对固态硬盘相差巨大。我们启动计算机时,如果操作系统不在固态硬盘上,启动用时至少30多秒;而操作系统在固态硬盘上,启动时间是几秒。

下图所示是三星固态硬盘官方公布的主要读写性能指标:

下图所示是希捷机械硬盘读写性能指标:

我们可以通过监听存储介质的性能指标来诊断程序在IO上的耗时,并针对性地优化对存储的访问(比如减少请求次数来减少IO)。存储介质的性能是一定的,我们需要对依赖它的持久化产品做文章,如MySQL数据库的慢查询,Redis存储的键值长度等。所有这些都需要我们去监控,通过监控推导出问题所在。

8)代码分析能力

作为IT部门的一员,不可避免地要和代码打交道,了解编程知识既能加深对性能测试的理解,还能提高和程序员沟通效率。更重要的是,做自动化测试、单元测试、性能测试、安全测试都离不开对代码的理解。所以我们要掌握一些使用率高的编程语言和脚本语言,如Java、Python等。

代码问题通常集中在事务、多线程、通信、存储及算法方面。测试人员可以不必去写一段优秀的代码,但要能够定位问题到代码段。

9)架构

高性能的系统架构与普通系统架构也不一样。性能优化或者性能规划要依照系统的用户规模来设计,了解架构有助于快速判断系统性能风险,有针对性地进行性能压测实验,提出合适的解决方案。

10)中间件性能分析

中间件的性能指标反映了系统的运行状况,我们要能够通过这些指标推导出系统的问题所在。有些可以通过调整中间件的配置来改善系统性能,比如用户请求过多,可以适当增大线程池;当JVM内存回收,特别是Full GC过于频繁时,我们就要分析到底是哪些程序导致了大量的Heap(堆)内存申请;当CPU过于繁忙时,我们会去分析哪个线程占用了大量CPU资源,通过线程信息定位到程序。这些都是常见的分析方法,也容易掌握,掌握这些分析方法能够解决80%以上的性能定位问题。

11)操作系统

操作系统统筹管理计算机硬件资源,针对不同业务,不同场景也会有一些可以优化的参数。我们首先要知道操作系统的限制,这需要从监控的指标中推导。常见调优方法有:文件句柄数设置、网络参数优化、亲和性设置、缓存设置等。

12)数据库分析

系统中流转的数据离不开持久化,持久化需要数据库。数据在数据库中的存储结构和搜索方式直接影响性能,大多数的性能调优都集中在数据库的存储及查询上。

学好数据库的理论知识,学会分析SQL的执行计划是一种基础技能。现在很多系统都用Redis来做热点数据的存储,在测试时对于影响Redis性能的因素要了解。比如Key-Value存储时Value过长,性能就会急剧下降,因为网络传输时数据包的MTU(最大数据包大小,Maximum Transmission Unit,这也是操作系统的知识点)通常是1500字节,大的数据包需要在网络中多次传输,当然效率低下。

如何优化数据库呢?最直接的想法是减少Value长度,分析为什么Value这么长,能否减少或者压缩,之后才是从数据库的业务逻辑上去考虑优化。

13)效率工具/持续集成

性能测试是一个反反复复的过程,发布后执行压测,分析问题、找到问题、修改问题,再发布、再执行压测。使用持续集成工具有利于提高工作效率。当下通常用Git/SVN来管理代码版本,使用Jenkins来做持续集成,同时我们也可以利用Jenkins来自动化性能压测过程。

云计算已成为主流技术,我们的服务会部署在云环境,因此对于云环境的了解自然不能落下。我们在云环境用虚机或容器(如Docker)技术来发布程序,这些对于性能的影响也是我们要考虑的问题,熟悉虚机与容器是自然的事。Docker容器是当前市场占有量最大的容器产品之一,对主流产品的学习也可以帮我们扩大知识面;Kubernetes已经成为容器编排产品的集大成者。

14)性能测试相关术语

(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):性能测试过程中为了模拟真实用户的业务处理过程,在测试工具中构建的基于事务、脚本、虚拟用户、运行设置、运行计划、监控、分析等一系列动作的集合,称之为性能测试场景。

此场景中包含了待执行脚本、脚本组、并发用户数、负载生成器、测试目标、测试执行时的配置条件等。简单地说,就是把若干个业务的性能测试脚本组织成一个执行单元,对执行单元进行一揽子的配置来保证测试的有效执行。比如负载测试时,我们可以设置一种下图所示的阶梯形负载增长场景。

(13)思考时间(Think Time):模拟正式用户在实际操作时的停顿间隔时间。从业务的角度来讲,思考时间指的是用户在进行操作时,每个请求之间的间隔时间;在测试脚本中,思考时间体现为脚本中两个请求语句之间的间隔时间。

(14)标准差(Std. Deviation):该标准差根据数理统计的概念得来,标准差越小,说明波动越小,系统越稳定;反之,标准差越大,说明波动越大,系统越不稳定。常见的标准差包括响应时间标准差、TPS标准差、Running Vuser标准差、Load标准差、CPU资源利用率标准差等。 

二、性能测试理论

1、性能测试简要

在处理性能问题方面,调优是主角。如果能进行性能调优,那就可以认为有能力解决性能问题。而具备这种能力的人才,也通常被认为是解决性能问题的专家。

在进行调优的时候,“性能测试”是不可或缺的。要让调优顺利进行下去,最重要的工作就是通过测试来验证。不过,如果将调优结果直接在生产环境中验证,会有一定风险,因此通常是在验证环境中获得性能测试的结果,来验证调优的成果。在通往调优专家或性能专家的道路上,性能测试可以说是最重要的要素。

1. 项目工程中的性能测试

普通的系统开发项目工程,粗略划分的话如图所示。粗体字部分就是与性能测试相关的任务。

其中,性能测试实际上主要在系统测试阶段执行。这是因为性能测试原则上是为了确认“系统在生产环境中运行时是否会有性能上的问题”,所以它是在完成集成测试后,确认系统能在生产环境中正常运行之后的阶段执行的。

即便如此,如果认为在进入系统测试阶段之前不需要考虑性能测试,那就错了。这里将为大家介绍项目的各个工程阶段必须考虑的事情和任务,以及如何有效地进行性能测试。

2. 不同职责的性能测试相关人员

1)项目经理

在运营项目的过程中,系统的性能问题想必尤其让项目经理(PM)感到头疼。有经验的项目经理一定知道,即使使用容量充足的硬件和已经验证过的应用程序,也有可能在意想不到的地方隐藏着性能问题的陷阱。

2)基础设施设计负责人

基础设施设计和应用程序设计在不同的流程中实施,很多情况下,基础设施会先于应用程序发布。在应用程序的细节还未确定的时候,基础设施设计负责人可能就会被问到“这个基础设施的架构能充分发挥性能吗”之类的问题。另外,流量控制和容量管理等与应用程序密切相关的部分也需要基础设施设计负责人来设计,这是很辛苦的。而如何对基础设施本身进行性能评估,这一点也是令人苦恼的地方。针对这些问题,如果能积极地提出方案或建议,比如在项目整体工程中,需要别的负责人提供哪些信息、确定哪些内容等,自己的任务也会顺利地进行下去。

3)基础设施运维负责人

基础设施运维负责人的任务是,拿到验证过的系统后,把系统部署到生产环境中运行。如果在运行过程中出现故障,发现存在性能问题,那么运维负责人就要参与并协助进行费力的调查分析工作。这个是非常规工作,为了尽量避免,就需要在接收系统之前进行完备的检查。

4)应用程序设计负责人

应用程序设计负责人一般不会考虑系统整体的性能,而是满脑子考虑如何使用新的框架和中间件来实现需要的业务和功能。虽然这一点的确很重要,但是如果之后出现了性能问题,比如在几乎忘记这个系统的相关内容的时候,甚至就需要重新进行系统设计。这是完全可以预见到的风
险。为了避免这样的风险,需要基于项目整体来确保应用程序的性能,以及为了充分保证性能,而不仅仅是完成需要的功能,应用程序设计负责人应该进行哪些工作。

5)性能测试负责人

性能测试负责人中可能有人之前已经参与过一些性能测试,应该能从这些经验中了解到为了顺利进行性能测试,不光要靠测试的技能,其周边相关领域的理解与协助,以及项目工程前期阶段的准备与条件的整理也是很重要的。

6)发包方

作为系统的发包方,可以说只要能拿到一套按预期运行的稳定的系统就足够了。但是在“按预期运行”“稳定”这些基准上,系统存在难点。保证10 个人同时使用的系统与保证 1000 个人同时使用的系统的开发费用和时间是完全不同的。另外,即使实际上是 10 个人在同时使用,根据这10 个人的操作的不同,需要的服务器规格也不同。甚至有时必要的性能需求不明确,只完成了明确规定的验证工作就交接、验收,就可能在实际使用的时候才意识到有问题。

开发者说到底也只是按照合同制作符合规定的产品,因此如果之后提出“想要再这样改一下”等要求,由于涉及需求变更,就需要支付额外的费用。因此,作为发包方,最好能把这些性能目标明确体现在需求中,把握好应该验证哪些方面。

2、性能测试现场问题

1. 不能在期限内完成

在制作应用程序的过程中第一次执行性能测试时,这是种比较常见的模式。即使你期待着在系统测试阶段仪式性地做一下性能测试,然后就这样告一段落,也还是有可能发生诸多状况,比如执行完性能测试后性能完全达不到要求,或者发生了意料之外的性能方面的故障,于是被迫解析、调优,重新进行测试,甚至有些情况下需要重新设计等,致使原本已经临近的发布日期延迟。

像这样,之所以后期工程中隐藏着性能问题,原因有如下几点。

  • 只有在生产环境中才会出现
  • 问题的显现需要很多条件(环境、数据、负载生成)
  • 因为特定的操作才导致发生性能问题

基于以上原因,一般至少为系统测试中的性能测试留出1 个月的时间。即使是认真地进行了准备、规划的项目,也需要这么久的时间。虽说在项目的收尾阶段很难保证这样长的时间来做性能测试,但如果不事先确保这么久的时间,非但不能完成完整的性能测试,更有可能因为没有达到预期的性能目标而被迫修改日程等,对自己的业务产生不良影响。

2. 性能很差!解决不了性能问题

如果执行性能测试后发生了性能问题,那该怎么办呢?首先,调查导致性能变差的原因。虽说如此,但可以怀疑的地方却有很多。比如网络、负载均衡器、Web 服务器、AP 服务器、开发应用程序的方式、数据库、存储、与其他系统有数据关联的部分、数据大小、SQL 等。

为了详细调查这些因素,就需要各个模块的专业知识。此外,对横跨多个领域的性能问题进行排查的时候,如果不能综合多个领域来考虑,负责人就只会一直说“我负责的那部分没有问题”,导致问题无法解决。此外,即使汇集了有专业知识的员工及体制,若没有采用正确的验证和分析方法,非但会使效率变差,有时甚至会让调查朝着错误的方向进行,最终也就找不到答案了。于是,我们就会陷入这样一种状态:虽然知道性能很差,但却无法查明原因,问题始终得不到解决。

特别是最近几年 Web 系统中模块的层级愈加复杂,问题越来越难排查,需要的专业知识范围越来越广,于是我们就越来越容易陷入这种状态。

3. 由于没有考虑到环境差异而导致发生问题

有时进行了性能测试,也确认了系统性能能够满足生产环境的要求,结果顺利发布后,却发现在生产环境中并没有获得预期的性能。这种情况下可能就会被追究责任,被追问性能测试的相关内容,比如“真的做了性能测试吗”“为什么会出现性能问题”等。

特别是如果在生产环境中运行的时候发生问题,比如系统停止工作,或者是出现故障,那么就会对
业务产生影响,有时甚至还会导致金钱上的损失,所以必须防止这种情况的发生。

至于为什么会出现此类问题,大家在调查原因时很容易忽视一点,那就是测试环境与生产环境之间的差异。比如,硬件和使用的基础软件的类型的差异、磁盘延迟的差异、网络延迟的差异等。除了以上容易想到的形式上的差异之外,在生产环境中,由于内存量很大,因此有可能导致软件内存管理模块的开销也很大。

另外,因为 CPU 核数很多,所以有可能导致多线程管理的开销也会变大。像这样,乍一看性能应该会提升,但实际上反而拖了后腿的情况也时有发生。

在无法准备和生产环境一样的性能测试环境的情况下,或者无法使用生产环境进行性能测试的情况下,当然就会有失败的风险。可能的话,在报价阶段就把准备与生产环境一样的测试环境的费用也一起考虑进去,或者准备好在生产环境中运行后出现问题的情况下可以立即切换回老系统的功能,也能让性能故障的损失降低到最小程度。

4. 压力场景设计不完备导致发生问题

在性能测试时完全达到了期望中的性能,但在同样结构的生产环境中实际运行时,即使是同样的处理数量,性能也很差,这样的情况时有发生。在这种情况下,重要的是首先确认执行了怎样的性能测试。

常见的有以下几种情况:

  • 实际上有多个种类的页面操作,但是测试中只执行了单一的页面操作,漏掉了更复杂的处理
  • 测试时和实际运行时访问登录、查找页面等负载较大的页面的比例有差异
  • 用户的停留时间超过测试时的预估,在多个页面之间迁移,这些迁移信息累积在会话中,导致使用的内存也超出预估

5. 没有考虑到缓冲、缓存的使用而导致发生问题

性能测试时性能很好,但是在生产环境中性能却很差,这种情况下就需要注意系统的缓冲和缓存的使用状态。

如果多次访问同一个页面,那么与该页面相关的缓存就会保存在 LB、Web 服务器、AP 服务器的缓存或数据缓存,或者 DB 的缓冲缓存等中,响应速度就会变快。速度变快就证明可以按照预期的那样使用功能,性能也就没有问题。但无论如何,测试时与实际运行时的缓存使用量都会出现差别。

以下是几种比较常见的情况:

  • 测试时只访问了同种类型的页面
  • 只使用了同一用户 ID 来访问
  • 只访问了相同的查找对象(商品名称等)
  • 查找时只使用了相同的过滤条件

以上这些情况下,在性能测试的时候,利用缓存能够最快地返回响应,所以性能很好,也能以很低的资源负载来完成处理。但是,真正在实际生产环境中运行的时候,就会出现各种各样的处理和访问,缓存使用率就不像测试时那样高,也就变成了慢响应和高负载的模式。

为了防止出现这样的情况,就需要在测试的时候预估好实际运行时的缓存命中率,并动态变更请求等。

6. 没有考虑到思考时间而导致发生问题

在性能测试时获得了很好的结果,但在生产环境中,即使施加了同样的处理负载,却还是达到了系统的性能极限,这种情况下我们能想到的另外一个原因就是压力测试场景的“思考时间”(Think Time)。这一点很容易被忽视,但却很常见。

思考时间指的是使用系统的用户的思考时间的预估值。用户会连续进行很多个处理,比如,打开页面后,进行登录→选择菜单→输入搜索关键字→从列表中选择条目→填写表单等操作,各个步骤之间的跳转并不是一瞬间完成的,用户在阅读或者填写时都会花费一定的时间(从几秒钟到几分钟)。

预想到实际的使用状态,正确地预算好时间来设计压力场景,或者只是单纯地使用测试工具在前一个处理完成后就立即发出下一个请求,这两种做法对系统的负载是有差异的。

对于服务器来说,即使在相同的吞吐(访问处理数 / 秒)状态下,也会由于思考时间的有无所造成的差异,导致 HTTP 并发连接数以及应用程序的会话保持数产生很大的不同。每秒访问处理数相同但思考时间不一样的情况下,思考时间越长,在系统上同时滞留的用户数和会话数也会越多。这就导致系统的内存和会话管理的压力出现差异。因此,在考虑压力场景时,如果没有把真实用户的思考时间纳入考量,那么这个性能测试就脱离了生产环境。

7. 报告内容难以理解导致客户不能认同

向客户报告性能测试结果与普通测试结果的情况是不一样的。普通测试的情况下,只要能按照事先设计的那样来运行,就是合格。也就是说,如果使用○ × 来判断,那么只要全部项目都是○,就能得到客户的认同。

性能测试则不是通过○ × 来判定,而是通过数字来评价的。如果只是简单地拿一个数字作为指标,达到这个指标就算合格,那么向客户报告说“响应时间在 3 秒以内”“达到了每秒处理 1000 条的要求”等,有时也可以获得客户的认可。

但实际上并没有这么简单,例如:“每秒处理条数是 1000 条的时候,响应时间是 2.5 秒,CPU 使用率是60%,但是当每秒处理条数是 1200 条的时候,响应时间变为了 4 秒,CPU 使用率是 80%。不过,场景的思考时间从平均 5 秒减少到 3 秒的时候,负载就下降了 30%。另外,在登录比例比较高的场景中,每100 次登录会有 2 次出错。”

如果像这样认真地报告结果,客户反而会表示“完全听不懂”。

实际上,客户关心的焦点集中在“在实际生产环境中运行时是否会出现性能方面的问题”。因此在报告性能测试结果时,有时不得不使用“在○○范围内的话没有问题,超过这个范围的话就会达到性能极限”这样的表述。

对此,客户可能会误解,觉得没有简明扼要地做出说明,甚至有些客户也可能完全不接受这种说明。

为了能获得客户的理解而进行解释的一个例子。缺失了这其中任何一个环节,逻辑上看起来都会比较跳跃,也就会被客户要求补充说明,或者被客户抱怨难以理解。

8. 客户因为存在不信任感而不能认同

一般来说,客户很容易对性能测试结果的报告产生不信任感。花费很多时间反复调优,反复分析,却没有得出明确的结论,或者对于“在生产环境中运行时是否会出问题”这样本质性的问题只能给出附带条件的、模棱两可的回答,就会让客户误以为是在糊弄他。很多情况下,由于不能很好地共享性能测试的整体过程,或者本来关于性能需求或性能测试设计的需求等的约定就很模糊,导致结论与评价基准等也变得很模糊,引起沟通不畅。

如果得不到客户的信任,那么项目方不论做什么都需要去消除客户的疑虑,以及做一些举证等不必要的工作,导致效率变差。特别是需要客户合作的项目,这样一来就会陷入一个非常不好的状态。

9. 测试很花时间

性能测试所花费的时间要远远超出想象。功能测试的情况下,一般只需执行预计的操作,看其结果是○还是×,就能立即得出答案。而性能测试则不一样。

一般来说,下面列举的各项工作会特别花费时间:

  • 搭建与生产环境一样的结构

在性能测试的时候,必须搭建与生产环境一样的结构,而这个搭建工作可能会与普通的搭建工作花费相同的时间。

这个结构所必需的项目主要有网络、存储、OS、中间件、实例生成、应用程序部署等。

  • 生成用于产生负载的环境与路径

把产生负载的工具连接到哪个网络点、形成怎样的工具配置结构,以及如何设置防火墙与负载均衡、如何设置负载工具本身等,这些工作与普通的搭建工作一样要花费很多时间。

在设计时没有考虑到性能测试的路径和配置,临近测试时才临时抱佛脚,讨论可配置的结构、预留地址和路由、设置机器、调整设置场所等,这种情况都是常有的事。

  • 设置用于性能测试的资源统计监控

即使进行普通的运维监控,有些情况下也需要通过别的方法来进行用于性能测试的资源统计。

通常的运维监控以 5 分钟的间隔来监控就足够了,而在性能测试的时候,想要按 1 分钟的间隔来监控,从而确认详细的运行情况为了便于在性能测试的时候分析瓶颈,想要更详细地进行资源统计
在上述很多情况下,都需要重新设置监控登记的设定。

  • 负载生成场景脚本的生成

为了实际运行负载生成场景,需要将其脚本化。即使是在测试准备阶段,这个工作有时也要花费相当长的时间。首先,需要讨论场景和分配等,比如什么样的页面操作流程更接近实际的负载。

接着,结合应用程序的特性,在登录的认证模拟器、Ajax 和 Web 服务器通信等的应对处理,以及多个查找关键字和菜单选项等的多样化设置方面,考虑将发向服务器的请求的参数中哪部分以变量形式实现等,然后据此生成场景脚本。

此外,以 CSV 等形式生成像数据银行(Data Bank)这样的登录 ID 或输入值列表,并设置为每次从中读取不同的数据,这部分做起来也很花时间。

举个极端的例子,即使是经验丰富的性能测试工程师,并且使用自己熟悉的方便的测试工具(Oracle Application Testing Suite 等),估计 1 天最多也只能完成 3 个脚本。不熟练或难度高的情况下,设置 1 星期也完成不了 1 个。

  • 生成用于性能测试的模拟数据

仔细想来,模拟数据的生成其实是一个很费力的工作。并不是简单地把随机的数字插入到数据库中就可以了,而是需要保证和实际相近的文字模式和散列程度(Cardinality,数据种类的浓度、分布的偏差值)等,而且要生成 100 万条数据本身也是件很复杂的事。多个系统间合作的情
况下,还需要以能够相互联动的数据结构来准备。

此外,在用生产环境生成测试数据的时候,需要先备份生产环境的数据,然后导入测试用的数据,在测试结束后再恢复生产环境数据。光是这个备份恢复工作,有时也可能会由于数据量大而耗费一整天的时间。

  • 性能测试的实施周期

实际执行一下性能测试就会发现,实施周期也远远超出想象。

后面我们还会提到,一个恰当的性能测试会逐渐增加并发度。如果按照预期的那样来实施测试,就会发现每次测试大概需要 30 分钟到 1 小时。

另外,在测试前后还要对测试结果进行分析和评价、备份与恢复数据、进行调优等。这样一来,即使是独占系统的状态下,实际上 1 天能完成的测试次数也不到 3 次。

  • 评价结果

评价测试结果有时也很花时间。例如,即使可以作出“速报中达到了每秒 1000 条的吞吐”这样的报告,但是各个场景、各个操作步骤的响应分别达到了预定的目标吗?资源使用率在各个统计对象中都处于目标范围内吗?在日志中出现了错误信息吗?从服务器返回的内容都是正常的内容吗?如果对此逐一进行检查的话,每次测试都将花费很长时间。

  • 排查瓶颈

排查瓶颈这项工作所需的时间完全由调查负责人的技术水平决定。如果是对网络、LB、AP、DB、存储、应用程序的内部结构和 Java VM 等的实现方式等全部了如指掌的超级工程师,那么不管怎样的性能问题,都能在比较短的时间内排查出来。

但是,实际上这样的人几乎很难找到,所以一般会各自分开调查,或者咨询产品供应商,对于异常的部分一个不漏地慢慢调查,最终排查出瓶颈,找出问题。如果技术水平比较低,可能到最后都不能找到瓶颈。这样的话,这个系统也就不能发布了。

也就是说,存在非常花费时间,或者不知道到底会花多少时间的风险。

  • 生成结果报告

简单来说,只要能在结果报告中记录测试结果、结论以及支持这些结果结论的数据并进行说明的话就足够了。不过,当涉及的数据量很大时,光是汇总统计、作图就很费时间。而且,在对复杂的瓶颈和调优进行说明时,还需要在资料中记述理论证明的过程,这就几乎是写一篇论文的工作量了。

此外,即使觉得结果报告没问题了,提交给客户之后,如果客户理解不了,或者是被指出缺失了什么重要的信息,也有可能要重新制作一份。

  • 制作性能测试计划、调整工作分配

如前所述,性能测试具有耗时较长的特性,因此有必要认真地制作计划,调整工作分配,并有条理地进行。

如果涉及的人员较多,或者系统的供应商很多,那么制作计划的商讨和调整、沟通、安排等工作甚至可能会花掉数周时间。

如果不尽早安排这些计划,就会导致性能测试的开始时间延迟,这一点请注意。

3、性能测试的种类

根据目的与情况的不同,性能测试可以分为很多类,接下来就让我们来看一下。

1. 实施的周期

在通常的开发、搭建项目的各个阶段,性能测试有几个变种。

作为判断性能的基准,最重要的测试就是(狭义的)“性能测试”。该测试也决定了系统能否发布。除此之外的其他测试则是为了更有效地运营项目或者其他目的而实施的。

“Rush Test”“压力测试”等不是根据测试目的来定义的,它们表示的只是测试的执行方式,因此在什么时间执行是由测试目的决定的。压力测试根据目的的不同,可以分为“性能测试”“临界测试”“耐久测试”等类型,具体做法都是在短时间内向系统发起大量的访问,以此来测量结果。一般会再现多个同时在线的用户的使用情况。在某些情况下,批处理时大量数据的流入也属于这一类。 

2. 狭义的性能测试

这个是最为重要的测试,目的是判断是否能达到要求的性能。

  • 实施时间

在系统测试阶段实施。前提是系统测试的功能部分已经全部通过测试,确定之后不再需要系统变更,并且已经做好了进行运用管理和批处理操作的准备,包含此动作的性能测试也已经准备好。如果没有满足这些前提条件,那么性能测试完成后,系统性能也有可能会发生变化,所以请尽量在上述前提下执行性能测试。

  • 测量项目

性能测试需要确认以下 3 个性能指标是否均已达成:

  1. 吞吐(处理条数 / 秒)
  2. 响应时间(秒)
  3. 同时使用数(用户数)

此外,确认服务器日志以及压力测试工具的记录,同时确认在测试中是否出现了错误信息。如果出现了错误信息,那么这个处理就有可能在执行过程中被跳过了,也就没有完成充分的性能验证。这种情况下就需要首先消除错误,然后再次执行测试。

如果已经定义了系统运行时资源使用率的上限(例如,遵守 CPU 使用率在 50% 以下等),则还需要一起确认资源使用率。

3. 临界测试(临界性能、回退性能、故障测试)

前面提到过,性能测试用于判定系统能否发布,而除此之外还存在从其他角度进行判定的压力测试。

  • 临界测试(最低性能)

测试是否达到了性能目标的基准。临界测试作为性能测试实施之前的预实施,不用进行太严密的用户场景定义与资源统计,其目的仅仅在于对能否处理预计的处理条数进行简单的确认。另外,在实际执行性能测试的时候,可能会出现负载对象的性能不足、施加负载的一方性能不足、结构错误等情况,临界测试的另一个目的就是发现这些问题。

若无需进行大规模的准备工作就能立即执行的话,应该在系统完成集成测试之后或之前执行一下。

1)实施时间

在大规模地正式实施性能测试之前,需要与各相关部门进行协调。有时候性能测试的实施时间是有限制的,因此测试负责人或服务器管理者应该事先确认好自己责任范围内的测试是否能正常进行。

2)测量项目

不需要花费太多精力,只要进行最小限度的确认就可以了。

  • 临界测试(最大性能)

这个测试的目的在于,在负载超过性能目标的情况下,把握系统承受程度的上限,以及当时的情况和瓶颈。

如果需求定义中没有要求进行临界性能的测量,那就没必要实施这个测试了。不过,在实际向客户报告测试结果的时候,可能会被问到“超过这个负载的时候能正常运行吗”“验证过流量控制和超时功能了吗”等问题。系统发布后,在超负载的情况下,如果流量控制、超时、运维监控的阈值检测机制等不能按照预想的那样正常运行,就会出问题,有时甚至会被当成残次品。为了消除这些隐患,我们要执行临界测试。要想通过验收,性能测试是必不可少的一项工作。而临界测试则非如此,而是项目方为了维护项目成果、避免风险而自发实施的测试。

1)实施时间

在系统测试阶段顺利通过性能测试后,如果有足够的时间就进行此项测试。这个时候可以进行两种测试。第一种是偏向基础设施的测试,在施加了与生产环境相似的流量控制的状态下,确认流量控制功能能否正常运行。另一种是在不进行流量控制的状态下,确认系统所能处理的上限以及这个时候的情况和瓶颈原因。在进行了这两个测试后,如果能基于明确的记录,对系统在超负载时的情况进行说明,客户一定能认可这个报告。在某些情况下,如果很好地执行了后面提到的“基础设施性能测试”,也可以不实施这里的第一种测试。

如果系统是横向扩展结构,那么也需要验证横向扩展结构下达到临界负载时的运行情况。理想情况下,在达到最大负载时,AP 服务器和 DB服务器的 CPU 使用率会达到 100%,或者网络带宽的使用率会接近100%,像这样施加负载让资源达到上限的话,那么作为临界性能测试的测试结果就可以说足够了。如果资源使用率没有达到 100% 就已经到了性能界线,吞吐也不能继续提升,或者增加负载也只是导致响应变差,那一定是哪里的设置存在瓶颈,必须搞清楚原因。

在从长远的角度计算系统使用人数的增加量以及针对这种情况的估算指标时,除了在纸上计算之外,还可以一并参考临界测试中阶段性的负载增加以及资源使用量。特别是与公司内部系统不同,在互联网系统中,可能会出现用户突然增加的情况,因此为了建立估算战略,事先进行测量是非常重要的。

2)测量项目

实施临界测试的方式是一直施加负载直到达到最大吞吐。使用压力测试工具增加并发度来生成负载的情况下,并发度增加到什么程度也是一个基准。此外,如前所述,为了判断资源是否用尽,也要一起参考服务器的 CPU 使用率。

  • 回退性能测试

回退性能测试也属于一种故障测试。在那些为了确保可用性而使用了冗余结构的系统中,我们需要验证当其中一部分处于停止状态时,是否能获得预期的性能。如果存在回退情况下的性能需求定义,就要进行这个测试。即使没有进行需求定义,如果在生产环境中运行时发生回退,导致没有获得预期的性能,也会很棘手,所以要尽可能地把这个测试加入到项目的验证计划中。

1)实施时间

分为两种情况,一种是在系统测试阶段的性能测试结束后执行,另一种是在后面将会提到的基础设施性能测试的过程中执行。如果冗余结构以及可用性功能在系统基础设施中就完成了,并且能够与搭载的应用程序剥离开来,那么只需在基础设施性能测试中执行回退性能测试就可以了。其他情况下,由于要让应用程序在类似于生产环境的环境中运行来进行测试,因此就要在性能测试之后来执行了。

不仅要对一部分处于停止状态的结构进行性能测试,也要对运行过程中停止或者再次启动时响应时间的变化进行确认。

2)测量项目

通常的检验方法是,作为测量指标,通过吞吐来确认最大性能,以及通过响应时间和是否发生错误来确认行为的变化。

3)故障测试

故障测试实际上并不属于性能测试的种类,一般被归类到集成测试或系统测试中执行的故障测试。不过,在发生与性能相关的故障时,需要结合压力测试一起实施,且故障测试与这里介绍的其他测试手法相近。

故障测试的目的是触发高负载时会出现的故障,判断那种情况下系统的行为以及错误恢复是否与预计的一样。特别是那些会出现高负载但又追求高可用性的系统,故障测试是必需的。

4)实施时间

如果作为基础设施可以分离开来的话,可以在集成测试和系统测试的基础设施上进行故障测试。如果不能分离,则可以在性能测试和临界测试等完成后,基于已经确立的性能测试和临界测试的手法来进行测试。

需要注意的是,如果在一般的性能测试和临界测试等场景中直接执行的话,有可能不能触发目标故障点,而是在别的地方出现瓶颈,导致不能触发希望出现的性能故障。这个时候,需要重新考虑负载场景、系统结构和设置,直到可以触发希望出现的性能故障。

5)测量项目

首先着眼于服务器以及负载终端的错误,确认那个时候的吞吐以及平均响应时间,将其作为参考指标。 

4. 基础设施性能测试

在最近的系统搭建中,大多会将应用程序和基础设施分离开来,分别制定搭建计划,然后在集成测试或系统测试中才将其汇合到一起。基础设施中包含中间件(DB 或 AP 服务器)的情况也很多。此外,基础设施作为基础,有专业负责人或供应商执行别的调度计划和检查,采用和应用程序不同的流程更容易推进。综合基础设施和私有云等一开始往往不能准备好应用程序,所以有时就需要在没有应用程序的情况下进行基础设施的发布及基础设施测试。

  • 基础设施性能测试的目的与必要性

基础设施性能测试是与应用程序分离开,从基础设施的观点来进行的性能测试。基础设施性能测试的目的是防止在后面的系统测试阶段中基础设施出现性能问题导致返工或计划变更。基础设施搭建团队通过预先进行负载试验,来尽量规避风险。

只要没有作为验收条件进行规定,基础设施性能测试就不是必需的。不过,如果在系统测试后的性能测试中才发现基础设施存在性能问题,返工成本就会很大,而且也有可能会影响到计划。为了不出现这样的情况,强烈建议在基础设施方面进行与实际生产环境相似的性能测试。

  • 实施时间

基础设施搭建结束后,在基础设施的集成测试中故障测试完成之后实施。

在基础设施上进行性能测试,其最大课题就是在应用程序还没有完成的状态下如何预估出需要的性能,以及怎样使用作为样本运行的应用程序。

  • 测量项目(样本应用程序)

评价的对象不同,测量的应用程序也不同。

从网络到Web服务器的基础设施性能测试在 Web 服务器上部署静态资源,然后对其发起大量访问就可以了。

包含依赖于会话的处理在内的基础设施性能测试使用依附于应用程序的样本程序。如果是WebLogic 的话,就经常使用PetShop 或 MedRec 等作为样本项目。这些程序会进行包含登录在内的会话管理,因此使用负载均衡器或 Web 服务器来进行会话和 cookie 的处理,然后分发,这样作为性能测试来说就足够了。

使用数据库或缓存网格(Cache Grid)或KVS的情况这些服务都不是直接从外部来访问,而大多是从 AP 服务器来访问的,因此很多时候不需要经过全部的基础设施。这种情况下,建议一个一个
地单独验证。各种测试工具应该都已经准备好了。

在进行数据库的基础设施测试时,为了按照事先想好的处理流程编写脚本,或者预设好实际的运行步骤并添加负载,使用 Oracle Real Application Testing 或者 Oracle Application Testing Suite 的 Load Testing Accelerator for ORACLE Database 也很方便。

在基础设施性能测试中,特别是与存储和数据库相关的测试,需要准备好与生产环境相同的数据量来验证。另外,测量备份和恢复所需的时间以及运维批处理能否在一定时间内完成也应该包含在基础设施性能测试中。

  • 基础设施性能测试的性能目标

在基础设施性能测试中,除了样本应用程序之外,另一个课题就是应该以什么样的性能目标作为基准。在讨论目标值时,一般按照下面的顺序进行。

① 提出性能目标信息

让应用程序开发部门提出严谨的性能目标信息。具体包括负载均衡器和Web 服务器上必需的同时连接数、每秒的请求数、网络流量(bps)等。DB 基础设施的情况下,只有简单的处理数和同时访问数是不够的,如果不能在应用程序这里更进一步,让其提示与业务相同级别的SQL 的同时执行信息,就不能完成充分的基础设施测试。

如果没有很好地定义这些指标就进行应用程序设计,就会在开发时忽视性能,因此应该对应用程序开发部门明确地提出要求。

② 自己预估

如果不能获取上述信息,或者对应用程序开发部分预估的信息不够放心,就需要自己来预估,顺便进行验证。

下表中汇总了预估目标信息所需的项目与知识:

相关内容

热门资讯

银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...