天天看点

不同视角下的软件性能与性能指标

对软件性能最普遍的理解就是软件处理的及时性。但其实,从不同的系统类型,以及不同的视角去讨论软件性能,都会有所区别。

文章目录

      • 不同类型的系统,软件性能的关注点各不相同
      • 终端用户眼中的软件性能
      • 运维人员眼中的软件性能
      • 软件设计开发人员眼中的软件性能
          • 算法设计包含的点:
          • 架构设计包含的内容
          • 性能最佳实践包括地点
          • 数据库相关地点
          • 软件性能的可测试性包含的点
          • 性能测试人员眼中的软件性能
      • 衡量软件性能的指标
          • 并发用户数
          • 响应时间
          • 系统吞吐量
        • 并发用户数、响应事件、系统吞吐量之间的关系

不同类型的系统,软件性能的关注点各不相同

  • Web 类应用和手机端应用,一般以终端用户感受到的端到端的响应时间来描述系统的能;
  • 非交互式的应用,比如典型的电信和银行后台处理系统,响应时间关注更多的是事件处理的速度,以及单位时间的事件吞吐量。

对同一个系统来说,不同的对象群体对软件性能的关注点和期望也不完全相同,甚至很多时候是对立的。这里,不同的对象群体可以分为四大类:终端用户、系统运维人员、软件设计开发人员和性能测试人员。

不同视角下的软件性能与性能指标

终端用户眼中的软件性能

从终端用户(也就是软件系统使用者)的维度来讲,软件性能表现为用户进行业务操作时的主观响应时间。具体来讲就是,从用户在界面上完成一个操作开始,到系统把本次操作的结果以用户能察觉的方式展现出来的全部时间。对终端用户来说,这个时间越短体验越好。

这个响应时间是终端用户对系统性能的最直观印象,包括了系统响应时间和前端展现时间。

  • 系统响应时间,反应的是系统能力,又可以进一步细分为应用系统处理时间、数据库处理时间和网络传输时间等;
  • 前端展现时间,取决于用户端的处理能力

    从这个角度来看,你就可以非常容易理解性能测试为什么会分为后端(服务器端)的性能测试和前端(通常是浏览器端)的性能测试了。

运维人员眼中的软件性能

除了包括单个用户的响应时间外,更要关注大量用户并发访问时的负载,以及可能的更大负载情况下的系统健康状态、并发处理能力、当前部署的系统容量、可能的系统瓶颈、系统配置层面的调优、数据库的调优,以及长时间运行稳定性和可扩展性。

大多数情况下,系统运维人员和终端用户是站在同一条战线上的,希望系统的响应速度尽可能地快。但,某些情况下他们的意见是对立的,最常见的情况就是,系统运维人员必须在最大并发用户数和系统响应时间之间进行权衡取舍。比如,当有两套系统配置方案可以提供以下系统能力的时:

  • 配置方案 A 可以提供 100 万并发访问用户的能力,此时用户的登录响应时间是 3 秒;
  • 配置方案 B 可以提供 500 万并发访问用户的能力,此时用户的登录响应时间是 8 秒。

    这时,从全局利益最大化角度来看,系统具有更大并发用户承载能力的价值会更大,所以运维人员一般都会选择方案 B。

目前,有些系统为了能够承载更多的并发用户,往往会牺牲等待时间而引入预期的等待机制。比如,火车票购票网站,就在处理极大并发用户时采用了排队机制,以尽可能提高系统容量,但却增加了用户实际感受到的响应时间。

软件设计开发人员眼中的软件性能

关注的是性能相关的设计和实现细节,这几乎涵盖了软件设计和开发的全过程。

在软件设计开发人员眼中,软件性能通常会包含算法设计、架构设计、性能最佳实践、数据库相关、软件性能的可测试性这五大方面。其中,每个方面关注的点,也包括很多。

算法设计包含的点:
  • 核心算法的设计与实现是否高效
  • 必要时,设计上是否采用 buffer 机制以题号性能,降低 I/O
  • 是否存在潜在的内存泄漏
  • 是否讯在并发环境下的线程安全问题
  • 是否存在不合理的线程同步方式
  • 是否存在不佳而李的资源竞争
架构设计包含的内容
  • 站在整体系统的角度,是否可以方便地进行系统容量和性能扩展
  • 应用集群地可扩展是否经过测试和验证
  • 缓存集群地可扩展性是否经过测验和验证
  • 数据库地可扩展性是否经过测试和验证
性能最佳实践包括地点
  • 代码是新啊是否遵守开发语言地性能最佳实践
  • 关键代码是否在白盒级别进行测试
  • 是否考虑前端性能地优化
  • 必要地时候是否采用数据压缩传输
  • 对于既要压缩又要加密地场景,是否采用先压缩后加密地顺序
数据库相关地点
  • 数据库表设计是否高效
  • 是否引入必要地索引
  • SQL 语句地执行计划是否合理
  • SQL 语句除了功能是否要考虑性能要求
  • 数据库是否需要引入读写分离机制
  • 系统冷启动后,缓存大量不命中地时候,数据库承载的压力是否超负荷
软件性能的可测试性包含的点
  • 是否为性能分析(Profiler)提供必要的接口支持
  • 是否支持高并发场景次啊的性能打点
  • 是否支持全链路的性能分析

    需要注意的是,软件开发人员一般不会关注系统部署级别的性能,比如软件运行目标操作系统的调优、应用服务器的参数调优、数据库的参数调优、网络环境调优。

系统部署级别的性能测试,目前一般是在系统性能测试阶段或者系统容量规划阶段,由性能测试人员、系统架构师,以及数据库管理员(DBA)协作完成。

性能测试人员眼中的软件性能

性能测试工程师关注的是算法设计、架构设计、性能最佳实践、数据库相关、软件性能的可测试性这五大方面。

在系统架构师、DBA,以及开发人员的协助下,性能测试人员既要能够准确把握软件的性能需求,又要能够准确定位引起“不好”性能表现的制约因素和根源,并提出相应的解决方案。

常常需要有以下技能:

  • 性能需求的总结和抽象能力;
  • 根据性能测试目标,精准的性能测试场景设计和计算能力;
  • 性能测试场景和性能测试脚本的开发和执行能力;
  • 测试性能报告的分析解读能力;
  • 性能瓶颈的快速排查和定位能力;
  • 性能测试数据的设计和实现能力;
  • 面对互联网产品,全链路压测的设计与执行能力,能够和系统架构师一起处理流量标记、影子数据库等的技术设计能力;
  • 深入理解性能测试工具的内部实现原理,当性能测试工具有限制时,可以进行扩展二次开发;
  • 极其宽广的知识面,既要有“面”的知识,比如系统架构、存储架构、网络架构等全局的知识,还要有大量“点”的知识积累,比如数据库 SQL 语句的执行计划调优、JVM 垃圾回收(GC)机制、多线程常见问题等等。

衡量软件性能的指标

衡量软件性能的三个最常用的指标:并发用户数、响应时间,以及系统吞吐量。

并发用户数

并发用户数,是性能需求与测试最常用,也是最重要的指标之一。它包含了业务层面和后端服务器层面的两层含义。

  • 业务层面的并发用户数,指的是实际使用系统的用户总数。但是,单靠这个指标并不能反映系统实际承载的压力,我们还要结合用户行为模型才能得到系统实际承载的压力。
  • 后端服务器层面的并发用户数,指的是“同时向服务器发送请求的数量”,直接反映了系统实际承载的压力。

eg:一个已经投入运行的 ERP 系统,该系统所在企业共有 5000 名员工都拥有账号,也就是说这个系统有 5000 个潜在用户。

根据系统日志分析得知,该系统最大在线用户数是 2500 人,那么从宏观角度来看,2500 就是这个系统的最大并发用户数。但是,2500 这个数据仅仅是说在最高峰时段有 2500 个用户登录了系统,而服务器所承受的压力取决于登录用户的行为,所以它并不能准确表现服务器此时此刻正在承受的压力。

假设在某一时间点上,这 2500 个用户中,30% 用户处于页面浏览状态(对服务器没有发起请求),20% 用户在填写订单(也没有对服务器发起请求),5% 用户在递交订单,15% 用户在查询订单,而另外的 30% 用户没有进行任何操作。那么此时,这 2500 个“并发用户”中真正对服务器产生压力的只有 500 个用户((5%+15%)*2500=500)。

在这个例子中,5000 是最大的“系统潜在用户数”,2500 是最大的“业务并发用户数”,500 则是某个时间点上的“实际并发用户数”。而此时这 500 个用户同时执行业务操作所实际触发的服务器端的所有调用,叫作“服务器并发请求数”。

从这个例子可以看出,在系统运行期间的某个时间点上,有一个指标叫作“同时向服务器发送请求的数量”,这个“同时向服务器发送请求的数量”就是服务器层面的并发用户数,这个指标同时取决于业务并发用户数和用户行为模式,而且用户行为模式占的比重较大。

因此,分析得到准确的用户行为模式,是性能测试中的关键一环。但,获得精准的用户行为模式,是除了获取性能需求外,最困难的工作。

目前,获取用户行为模式的方法,主要分为两种:

  • 对于已经上线的系统来说,往往采用系统日志分析法获取用户行为统计和峰值并发量等重要信息;
  • 而对于未上线的全新系统来说,通常的做法是参考行业中类似系统的统计信息来建模,然后分析。
响应时间

“应用系统从请求发出开始,到客户端接收到最后一个字节数据所消耗的时间”,是用户视角软件性能的主要体现。

响应时间,分为前端展现时间和系统响应时间两部分。其中,前端时间,取决于客户端收到服务器返回的数据后渲染页面所消耗的时间;而系统响应时间,又可以进一步划分为 Web 服务器时间、应用服务器时间、数据库时间,以及各服务器间通信的网络时间。

除非是针对前端的性能测试与调优,软件的性能测试一般更关注服务器端。但是,服务器端响应时间的概念非常清晰、直接,就是指从发出请求起到处理完成的时间,没有二义性;而前端时间的定义,在我看来存在些歧义。

虽然前端时间一定程度上取决于客户端的处理能力,但是前端开发人员现在还会使用一些编程技巧在数据尚未完全接收完成时呈现数据,以减少用户实际感受到的主观响应时间。也就是说,我们现在会普遍采用提前渲染技术,使得用户实际感受到的响应时间通常要小于标准定义的响应时间。

鉴于此,响应时间的标准定义就不尽合理了,尤其是对于“接收到最后一个字节”。

比如:加载一个网页时,如果 10 秒后还是白屏,那你一定会感觉很慢、性能无法接受。但是,回想一下你曾经上新浪网的经历,当加载新浪首页时,你应该不会感觉速度很慢吧。其实,实际情况是,新浪首页的加载时间要远大于 10 秒,只是新浪采用了数据尚未完全接收完成时进行呈现的技术,大大缩短了用户主观感受到的时间,提升了用户体验。

所以,严格来讲,响应时间应该包含两层含义:技术层面的标准定义和基于用户主观感受时间的定义。而在性能测试过程中,我们应该使用哪个层面的含义将取决于性能测试的类型。显然,对于软件服务器端的性能测试肯定要采用标准定义,而对于前端性能评估,则应该采用用户主观感受时间的定义。

系统吞吐量

系统吞吐量,是最能直接体现软件系统负载承受能力的指标。

这里需要注意的是,所有对吞吐量的讨论都必须以“单位时间”作为基本前提。

吞吐率 = 吞吐量 / 单位时间。

对性能测试而言用“Requests/Second”“Pages/Second”“Bytes/Second”来衡量吞吐量。当然,从业务的角度来讲,吞吐量也可以用单位时间的业务处理数量来衡量。以不同方式表达的吞吐量可以说明不同层次的问题。比如:

  • “Bytes/Second”和“Pages/Second”表示的吞吐量,主要受网络设置、服务器架构、应用服务器制约;
  • “Requests/Second”表示的吞吐量,主要受应用服务器和应用本身实现的制约。

    虽说吞吐量可以反映服务器承受负载的情况,但在不同并发用户数的场景下,即使系统具有相近的吞吐量,但是得到的系统性能瓶颈也会相差甚远。

比如,某个测试场景中采用 100 个并发用户,每个用户每隔 1 秒发出一个 Request,另外一个测试场景采用 1000 个并发用户,每个用户每隔 10 秒发出一个 Request。显然这两个场景具有相同的吞吐量, 都是 100 Requests/second,但是两种场景下的系统性能拐点肯定不同。因为,两个场景所占用的资源是不同的。

这就要求性能测试场景的指标,必然不是单个,需要根据实际情况组合并发用户数、响应时间这两个指标。

并发用户数、响应事件、系统吞吐量之间的关系

了解了概念后以一个日常生活中的体检为例说明他们之间的关系和约束。假设我们去体检中心做入职体检,通常是先去前台等级个人信息并领取体检单,然后根据具体的项目依次完成不同科室的检查。

假设一共有 5 个科室,每个科室有 3 个候诊室,通常你会选择先做排队人数较少的检查项目,直至完成 5 个科室的全部检查,最后离开体检中心。

现在,我们做个类比:把整个体检中心想象成一个软件系统,从你进入体检中心到完成全部检查离开所花费的时间就是响应时间,而同时在体检中心参加体检的总人数就是并发用户数,那么系统吞吐量就可以想象成是单位时间内完成体检的人数,比如每小时 100 人。

如果你到达体检中心的时间比较早,这时人还很少,5 个科室都不用排队,那么你就能以最短的时间完成体检。也就是说,当系统的并发用户数比较少时,响应时间就比较短;但是由于整体的并发用户数少,所以系统的吞吐量也很低。

从中,我们可以得出这样的结论:系统并发用户数少时,系统的吞吐量也低,系统处于空闲状态,把这个阶段就称为“空闲区间”

如果你到达体检中心时,这里的人已经比较多了,只有部分科室不需要排队,但好在每个科室都有 3 个候诊室同时进行检查,所以排队时间不会很长,你还是可以在较短的时间完成体检。也就是说,当系统的并发用户数比较多时,响应时间不会增加太多,因此系统的整体吞吐量也随着并发用户数的变大而变大的。

从中,我们可以得出这样的结论:当系统整体负载并不是很大时,随着系统并发用户数的增长,系统的吞吐量也会随之呈线性增长,我们往往把这个阶段称为 “线性增长区间”。

但是,当体检中心的人越来越多时,每个科室都需要排队,而且每个科室的队伍都很长,你每检查完一个项目都要花很长时间去排队进行下一个检查项目。这样一来,你完成体检的时间就会明显变长。也就是说,系统的并发用户数达到一定规模时,每个用户的响应时间都会明显变长,所以系统的整体吞吐量并不会继续随着并发用户数的增长而增长。

从中,我们可以得出这样的结论:随着系统并发用户数的进一步增长,系统的处理能力逐渐趋于饱和,因此每个用户的响应时间会逐渐变长。相应地,系统的整体吞吐量并不会随着并发用户数的增长而继续呈线性增长。我们往往把这个阶段称为系统的“拐点”。

最糟糕的情况来了,如果人继续增加,连排队、站人的地方都没有了,候诊室中检查完的人出不来,排队的人又进不去。也就是说,系统的并发用户数已经突破极限,每个用户的响应时间变得无限长,因此系统的整体吞吐量变成了零。换言之,此时的系统已经被压垮了。

从中,我们可以得出这样的结论:随着系统并发用户数的增长,系统处理能力达到过饱和状态。此时,如果继续增加并发用户数,最终所有用户的响应时间会变得无限长。相应地,系统的整体吞吐量会降为零,系统处于被压垮的状态。我们往往把这个阶段称为“过饱和区间”。

继续阅读