阿里巴巴技术质量新人手册7-多面手之性能测试
概念&目的
本周分享的性能测试,主要面向的是服务端的性能测试。
性能测试是从业务中提取压测模型,然后利用压测工具按照模型制造压测流量,并对目标应用集群进行施压,在施压过程中观察应用集群的性能表现和发掘性能瓶颈的测试行为。
当前性能测试主要分为线上压测和线下压测。线上压测主要通过全链路压测执行,线下压测是单机(或者小集群)压测。全链路压测请看全链路压测章节,本节主要讨论通用性能测试方案和流程。
常用指标
1. 虚拟用户
虚拟用户,模拟真实业务逻辑步骤的虚拟用户,虚拟用户模拟的操作步骤都被记录在压测脚本里。压测脚本用于描述虚拟用户在场景中执行的操作。
2. Transaction压测事务
事务是性能测试脚本的一个重要特性。要度量服务器的性能,需要定义事务,每个事务都包含事务开始和事务结束标记。事务用来衡量脚本中一行代码或多行代码的执行所耗费的时间。可以将事务开始放置在脚本中某行或者多行代码的前面,将事务结束放置在该行或者多行代码的后面,在该脚本的虚拟用户运行时,这个事务将衡量该行或者多行代码的执行花费了多长时间。
3. TPS每秒事务数
TPS(Transaction Per Second)每秒钟系统能够处理的交易或事务的数量,它是衡量系统处理能力的重要指标。
备注:在日常工作中也会用到TPS和QPS,在应用层,所有的请求都可以用QPS或者TPS来表示;但在DB层,TPS和QPS有区别,QPS指的是select的请求量,TPS指的是insert、update和delete的请求量
4. Peak PV 高峰Page View
即PV峰值,指一天中PV数达到的最高峰。
5. Concurrency并发
并发分为狭义和广义两类。狭义的并发,即所有的用户在同一时刻做同一件事情或操作,这种操作一般针对同一类型的业务,或者所有用户进行完全一样的操作,目的是测试数据库和程序对并发操作的处理。
广义的并发,即多个用户对系统发出了请求或者进行了操作,但是这些请求或操作可以是不同的。对整个系统而言,仍然有很多用户同时进行操作。
狭义并发强调对系统的请求操作是完全相同的,多适用于性能测试、负载测试、压力测试、稳定性测试场景;广义并发不限制对系统的请求操作,多适用于混合场景、稳定性测试场景。
6. 压测场景
为了模拟真实用户的业务处理过程,从被压测业务中抽取出目标压测接口,并封装成压测脚本,该抽出出来的目标压测接口即为一个压测场景。
7. Response Time响应时间(RT)
响应时间是指从客户端发一个请求开始计时,到客户端接收到从服务器端返回的响应结果结束所经历的时间,响应时间由请求发送时间、网络传输时间和服务器处理时间三部分组成。
8. Think Time思考时间
模拟正式用户在实际操作时的停顿间隔时间。从业务的角度来讲,思考时间指的是用户在进行操作时,每个请求之间的间隔时间。在测试脚本中,思考时间体现为脚本中两个请求语句之间的间隔时间。
9. CPU资源
CPU资源是指性能测试场景运行的这个时间段内,应用服务系统的 CPU资源占用率。CPU资源是判断系统处理能力以及应用运行是否稳定的重要参数。应用服务系统可以包括应用服务器、Web服务器、数据库服务器等。
10. Load负载
系统平均负载,被定义为在特定时间间隔内运行队列中的平均进程数。如果一个进程满足以下条件则其就会位于运行队列中:
- 它没有在等待 I/O 操作的结果。
- 它没有主动进入等待状态(也就是没有调用“wait”)。
- 没有被停止(例如:等待终止)。
性能测试策略
1. 模拟生产线真实的硬件环境。
架设与生产环境相似的性能测试环境,使用物理机作为服务器。例如,使用4核CPU、8G内存的机器模拟生产环境的应用服务器;使用共用存储的数据库服务器等。
2. 服务器置于同一机房,最大限度避免网络问题。
所有性能测试的服务器都放置在同一个机房,属于同一个网段,服务器与服务器之 间的网络交互通过交换机进行。
3. 以 PV 为切入点,通过模型将其转换成性能测试可量化的 TPS。
互联网的特点,是在线用户不断变化,很难统计到具体某个应用的在线用户数;但是页面是固定的,可以统计的。用户U访问了P页面的行为,是能捕获的。换句话,对于页面 P,不管当前有100个用户,还是1000个用户在使用,页面的Page View都是可以统计到的。因此,以PV为性能测试切入点,作为性能测试的突破口。通过这种方式,可以将页面流量直接转化成Page View,作为性能测试的预期目标,而削弱在线用户数和并发用户数。得到PV数值之后,再通过PV计算模型、PV->TPS转换模型,将它转化成测试工具可以衡量的指标TPS,从而使复杂的模型变得简单化、可衡量化。
4. 性能测试数据分为基础数据和业务数据两部分。
性能测试数据库和功能测试库相互独立。性能测试数据分为基础数据和业务数据两 部分。基础数据,指为了使表中的数据达到一定的数量级而填充的数据,目的是测试出数据库索引是否足够优化、表空间、索引空间是否足够;业务数据,指为了使被测系统 能够按业务逻辑运行起来的数据,通俗而言,就是功能测试所使用的数据,目的是测试 出SQL语句是否足够优化、代码是否足够优化等。
5. 日志等级设置成 warn,避免大量打印日志对性能测试结果的影响
JAVA 日志,分为 info ,debug ,warn ,error 四个级别。打印日志会消耗服务器的IO,也会消耗硬盘存储空间。在性能测试过程中,如果频繁打日志,会导致IO消耗大,从而消耗服务器的CPU资源;也会导致日志文件过大, 写入困难,程序执行速度变慢等问题。而 info 和 debug 两个级别,都会打印大量日志。因此,性能测试过程中,选择将日志等级设置成warn级别,只打印出warn和 error 的日志,即减少日志输入数量,又能监控到性能测试过程中出现的错误,一举两得。
6. 屏蔽缓存,模拟最坏的情况
缓存,是页面性能优化的手段之一。对于非频繁变化的数据,可以在容器中缓存起来,提高读的性能,同时减轻数据库压力。缓存必须在数据被访问过后才会生效,另外,缓存失效后需要重启缓存,即在系统刚发布、重新缓存过程中,用户访问速度会变慢、数据库压力也会加大。为了避免类似系统刚上线,数据库就受到Load过高,甚至面临崩溃的灾难。在性 能测试过程中,我们需要模拟没有缓存的场景。
7. 先单场景,后混合场景,确保每个性能瓶颈都得到调优。
性能测试过程中,选择先执行单场景,后执行混合场景的策略。单场景执行,可以详细测试到某个页面、某个接口等“单点”的性能,这种方式有 利于定位性能瓶颈,优化代码。对于使用 HSF 方式通信的系统来说,这样的针对性测试效果非常显著。混合场景,在单场景都优化完成后,按照一定的比例对各种场景进行组合,测试整个应用系统的总体性能表现。其实,单场景和混合场景,两种都不可缺少。
8. 拆分问题,隔离分析,定位性能瓶颈。
性能测试过程中出现的小概率事件,往往隐藏着大的性能瓶颈。为了精确定位到瓶 颈,需要将各个应用,或者一个应用的各个环节进行拆分,逐渐隔离掉没有问题的部分, 然后在可能有问题的部分进行再排查,直到瓶颈定位到为止。
9. 根据业务系统要求,来判断被测性能点通过与否。
结合当前系统复杂度和业务能力要求,来评判当前性能点的性能结果是否满足需求。
10. 性能瓶颈
录入AONE进行跟踪,对于不能在当前项目中解决的性能 bug,邀请专家组进行风险评估。
性能测试评估
制定性能测试策略之后,如何开展性能测试工作呢?在实施性能测试之前,需要对被测项目做相应的评估。实施前的评估,主要目的是明确是否需要做性能测试和确立性能点,明确该测什么、期望值是多少。测试期望值也会根据情况评估,要求被测系统能满足将来一定时间段的压力。性能测试评估分为测试前的评估和测试后的评估。这里重点阐述测试前的评估。主要从以下 4 个维度进行测试前的评估:
- 关键业务。
- 日PV量。
- 逻辑复杂度。
- 运营推广计划。
1. 关键业务
首要维度,是确定被测项目是否属于关键业务,有哪些主要的业务逻辑点,特别是跟交易链路息息相关的功能点。例如,购物车系统,用于购物车浏览、购物车添加、购物车删除、购物车凑单等功能。通过评估,从中筛选出购物车浏览和添加这两个主要业务涉及的功能。如果项目(或功能点)不属于关键业务(或关键业务点),则可转入第二、三、四个维度进行评估。
2. 日PV量
第二个维度,是界定被测项目各功能点的PV量(或者日请求量)。如果PV量很高,系统压力很大,而且又是关键业务,该项目需要做性能测试;而且其关键业务点,可以被确定为性能点。如果PV量不高,系统压力不大,但却是关键业务点,则依据第三个或第四个维度来判断。
3. 逻辑复杂度
第三个维度,是判定被测项目各功能点的逻辑复杂度。如果一个主要业务的PV量不高,但是逻辑很复杂,则也需要通过性能测试。原因是,在集团庞大的业务系统调用中,当某一个环节响应较慢,就会影响到其它环节,造成雪崩效应。
4. 运营推广计划
第四个维度,是根据运营的推广计划来判定待测系统未来的压力。未雨绸缪、防患于未然、降低运营风险是性能测试的主要目标。被测系统的性能不仅能满足当前压力,更需要满足未来一定时间段内的压力。因此,事先了解运营推广计划,对性能点的制定有很大的作用。例如,运营计划做活动,要求系统每天能支撑多少PV、多少UV,或者一个季度后,需要能支撑多大的访问量等等数据。当新项目(或功能点)属于运营重点推广计划范畴之内,则该项目(或功能点)也需要做性能测试。
5. 其它
以上4个评估维护,是相辅相成、环环相扣的,它们合成一个维度集。在实际工作中,应该具体问题具体分析。例如,当一个功能点不满足以上4个维度,但又属于内存高消耗、CPU 高消耗时,也可列入性能测试点行列。
性能测试类型
随着单位时间流量的不断增长,被测系统的压力不断增大,服务器资源会不断被消耗,TPS 值会因为这些因素而发生变化,而且符合一定的规律,性能测试压力变化模型如图1所示。
图1 性能测试类型图
图1中:
- a 点:性能期望值
- b 点:高于期望,系统资源处于临界点
- c 点:高于期望,拐点
- d 点:超过负载,系统崩溃
由上述压力变化模型,将性能测试分成狭义的4种类型:
- a. 性能测试。
- b. 负载测试。
- c. 压力测试。
- d. 稳定性测试。
1. 性能测试
定义:狭义的性能测试,是指以性能预期目标为前提,对系统不断施加压力,验证系统在资源可接受范围内,是否能达到性能预期。
运用场景:此类型的测试目前最常见。每个项目的性能点,都需要做性能测试。
2. 负载测试
定义:狭义的负载测试,是指对系统不断地增加压力或增加一定压力下的持续时间,直到系统的某项或多项性能指标达到安全临界值,例如某种资源已经达到饱和状态等。
运用场景:此类型的测试目前运用得比较少。一般情况下,是以服务器资源安全临界值为界限的测试。如果要模拟某个应用在指定服务器上最大且安全的负载量,则属于负载测试。
3. 压力测试
定义:狭义的压力测试,是指超过安全负载的情况下,对系统不断施加压力,是通过确定一个系统的瓶颈或不能接收用户请求的性能点,来获得系统能提供的最大服务级别的测试。
运用场景:此类型的测试目前运用得比较少。但对于大型的共享中心或者核心的应用,也会用到。
4. 稳定性测试
定义:狭义的稳定性测试,是指被测试系统在特定硬件、软件、网络环境条件下,给系统加载一定业务压力,使系统运行一段较长时间,以此检测系统是否稳定,一般稳定性测试时间为n*12小时。
运用场景:此类型的测试目前也最常见,针对需要长时间稳定运行的性能点,需要执行稳定性测试。往往在一个项目的性能测试过程中,会划分出优先级较高的性能点,做稳定性测试。例如:宝贝详情页面等等。
性能测试执行方法
性能测试通常采用先单场景,后混合场景的执行方法。
1. 单场景
针对单个性能测试点,构建一个性能测试场景,而进行的性能测试。单场景适用于性能测试、负载测试、压力测试、稳定性测试。
2. 混合场景
为了尽量模拟生产线上运行的业务压力或用户使用场景,测试系统的整体性能是否满足性能需求,把经过一定规则筛选的性能测试点,按照合乎实际逻辑的虚拟用户请求、并发,组合成一个混合场景。
混合场景的特征,通常包含两个或者两个以上的脚本组,执行时间较长。混合场景通常在稳定性测试、负载测试中使用。
性能监控
性能监控需要实时观察性能测试过程中各项指标是否正常,包括应用服务器、数据库、中间件、网络等方面,保证测试前提,记录测试数据,输出监控结果。更重要的是,监控的过程是发现系统瓶颈的过程,是性能分析、性能通过与否、性能报告输出等环节的基础和依赖。
监控需要使用不同的工具,结合系统日志、应用和服务器所反映的多项指标,记录监控数据。以下阐述了监控指标、监控工具和监控步骤等三个部分内容。
1. 监控指标
性能测试通常需要监控的指标包括:
-
服务器
具体包括CPU、Memory、Load、I/O、Disk等。
-
数据库
具体包括缓存命中、索引、单条SQL性能、数据库线程数、数据池连接数等。
-
中间件
具体包括线程数、连接数、日志输出等。
-
网络
具体包括防火墙、网卡、网线、吞吐量、吞吐率等。
-
应用服务
具体包括JVM内存使用和回收、JAVA内存使用、FullGC频率、JAVA类装入和卸载、日志、线程运行状态(阻塞、等待、正常运行)等。
-
性能监控指标
具体包括用户执行情况、场景状态、事务响应时间、TPS、Load、CPU分析图表等。
-
测试机资源
具体包括CPU、Memory、网络、日志输出、磁盘空间、负载生成器评估等。
2. 监控工具
性能测试通常采用下列工具进行监控:
-
JStat
Jstat是JDK自带的一个轻量级小工具。全称“Java Virtual Machine statistics monitoring tool”,它位于java的bin目录下,它主要利用了JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heapsize和垃圾回收状况的监控。可见,Jstat是轻量级的、专门针对JVM的工具,很实用。
-
JConsole
JConsole是一个用JAVA写的GUI程序,用来监控VM,并可监控远程的VM,易用且功能强大。具体可监控JAVA内存、JAVA CPU使用率、线程执行情况、加载类概况等,JConsole需要在JVM参数中配置端口才能使用。由于是GUI程序,界面可视化,这里就不做详细介绍。
-
JMap
Jmap是一个可以输出所有内存对象的工具,甚至可以将VM中的heap以二进制输出成文本,可以监控JAVA程序是否有内存泄漏。
-
JProfiler
JProfiler分析工具是目前功能相对比较全的JAVA剖析工具(profiler)。它可以详细的剖析CPU、线程和内存的使用信息。
JProfiler可提供许多IDE整合和应用服务器整合功能。JProfiler直观式的界面让你可以方便的找到性能瓶颈、抓住内存泄漏(memoryleaks)、并解决多线程的问题。可以对内存的GC的资源回收器做深入的分析,可以轻易找出内存泄漏;
JVM内存的快照(snapshot)模式可以让未被引用(reference)的对象、稍微被引用的对象、或在终结(finalization)序列的对象都清晰地呈现出来。
性能分析
性能分析从性能测试分析原则、分析信息来源、分析标准。
1. 分析原则
在分布式架构下,性能瓶颈分析也变得相对困难。针对不同的应用系统、不同的测试目标、不同的性能关注点,根据性能指标的表现,采用“拆分问题,隔离分析”的方法进行分析,即逐步定位、从外到内、从表及里、逐层分解、隔离排除。
性能分析,可按以下顺序: 中间件瓶颈(tomcat参数配置、数据库参数配置等)->应用服务日志->本应用的性能瓶颈(代码、SQL语句、索引、业务逻辑、线程池设置、算法)->服务提供者的性能瓶颈->相关联的底层存储应用的性能瓶颈
注:以上是比较通用的分析过程,具体性能测试查找瓶颈过程中,需要具体问题具体分析。
2. 分析信息来源
a) 监控工具所采集的信息。包括压测工具产出的数据以及监控的机器数据。具体为:TPS、响应时间、用户并发数、JVM内存、FullGC频率、CPU利用率、Load等。b) 应用服务器的日志。包括本应用和远程应用的错误日志、超时日志等。c) 项目配合人员所提供的信息。包括数据库监控信息、开发人员提供的代码逻辑信息等。
3. 分析标准
通过性能指标的表现形式,分析性能是否稳定。比如: a) 响应时间是否符合性能预期,表现是否稳定。b) 应用日志中,超时的概率,是否在可接受的范围之内。c) TPS维持在多大的范围内,是否有波形出现,标准差有多少,是否符合预期。d) 服务器CPU、内存、Load是否在合理的范围内,等等。
性能测试流程
测试流程中的主要活动描述如下:
- 评估是否需要进行性能测试:在项目立项前的技术方案阶段,PTM/PM和PDM评估出是否需要做性能测试。
- 性能测试资源分配:当前主要由各业务线的开发和功能测试同学负责进行性能测试。
- 制定性能测试计划:根据项目(日常)计划和功能测试计划,制定性能测试计划。
- 编写性能测试设计方案:在UC评审之后,邀请PM、PDM、测试负责人,一起细化性能测试需求,编写性能测试方案。
- 评审性能测试设计方案:组织性能测试设计方案评审会议,邀请PM、系统设计人员、测试负责人、DBA等共同参与。评审主要是针对测试目标、测试策略和测试数据进行确认,并提出改进意见,达成一致
- 提交代码、配合搭建环境、配合数据准备:线下测试,可在aone的项目环境中搭建性能测试环境,同时准备压测数据和压测脚本。
- 执行性能测试:第一轮功能测试通过之后,执行性能测试,执行脚本需要符合规范。分析性能测试结果,找到性能瓶颈,配合开发人员进行性能调优,每天产出性能测试日报,并判断性能测试结果是否满足期望
- 性能调优:PM、性能测试工程师、DBA共同参与性能测试调优方案的制定工作。代码的调优工作,由PM或者PM指定开发人员完成。
- 编写性能测试报告:编写性能测试报告,阐明性能测试目标、性能测试环境、性能测试数据构造规则、性能测试策略、性能测试结果、性能测试调优说明、性能测试过程中遇到的问题和解决办法等。