【软件性能测试与调优实践】性能测试、分析与调优基础
发布日期:2021-06-30 21:35:56 浏览次数:3 分类:技术文章

本文共 6769 字,大约阅读时间需要 22 分钟。

性能测试除了为获取性能指标外,更多是为了发现性能瓶颈和性能问题,然后针对性能问题和性能瓶颈进行分析和调优

(一)性能测试的基础

性能可以理解为一个系统实现其功能的能力

宏观:

  • 系统能够稳定运行
  • 高并发访问时系统不会出现宕机
  • 系统处理完成用户请求需要的时间
  • 系统能够同时支撑的并发访问量
  • 系统每秒可以处理完成的事务数

微观:

  • 处理每个事务的资源开销(包括CPU、磁盘I/O、内存、网络传输带宽)
  • 服务连接数
  • 服务线程数
  • JVM Heap使用情况
  • 内存的分配和回收是否及时
  • 缓存规则的命中率

不同的群体对性能的理解可能存在很大的差异

普通的用户更关心响应时间和稳定性:

  • 访问页面响应还让我等多久才能加载出来?
  • 为什么有时候会访问失败?为什么会出现错误502?

架构师和工程师更关心架构设计和代码编写的性能:

  • 应用架构设计是否合理?
  • 技术架构设计是否合理?
  • 数据架构设计是否合理?
  • 部署架构设计是否合理?
  • 代码是否存在性能问题?
  • JVM中是否有不合理的内存分配和使用?
  • 线程同步和线程锁是否合理?
  • 代码的计算算法是否可以优化CPU的消耗时间?

运维工程师更关注系统的监控和稳定性:

  • 服务器各项资源使用率是否正常范围内?
  • 数据库的链接数是否在正常范围内?
  • SQL执行时间是否正常,是否存在慢查询日志?
  • 系统能否支撑7*24小时连续不间断的业务访问?
  • 系统是否高可用?服务器节点宕机是否会影响用户使用?
  • 节点扩容是否可以提高系统的性能?

(二)性能测试场景

  • 业务场景

指系统的业务处理场景,描述具体的用户行为,通过用户行为分析,以划分不同的业务场景,是性能测试时场景设计的重要来源

  • 测试场景

对业务场景的真实模拟,测试场景的设计应该尽可能贴近真实的业务场景,有时候由于测试的条件限制,需要对脚本调整,使得脚本模拟的场景尽可能贴近真实

  • 单场景

只涉及单个业务流程的测试场景,目的是测试系统的单个业务处理能力是否达到预期,并且得到系统资源利用率正常情况下的最大TPS、平均响应时间等性能指标

  • 混合场景

测试场景中涉及多个业务流程,每个业务流程按照不同的比重混合,尽可能符合业务的需要,测试混合业务处理能力是否满足预期要求,并且评估系统的混合业务处理容量最大能达到多少

(三)性能测试指标

响应时间

请求或者某个操作从发出的时间到收到服务器响应的时间的差值就是响应时间
请求可能经过的处理路径和节点,那么响应时间的计算方式就是所有路径消耗的时间和每个服务器节点处理时间的累加,通常是网络时间+应用程序的处理时间
在这里插入图片描述

TPS

事务是自定义的某个操作或者一组操作的集合
TPS是Transaction Per Second的缩写,即系统每秒能够处理的交易和事务的数量,一般统计的是每秒处理的事务数

并发用户数

在真实的用户操作中,用户的每个相邻操作之间都会有一定的间隔时间(用户思考时间)
并发用户中有绝对并发和相对并发

  • 绝对并发:某个时间点同时一起向服务器发起的请求的并发用户数
  • 相对并发:一段时间内向服务器发出请求的并发用户总数

单就性能指标而言,系统的并发用户数是指系统可以同时承载的正常使用系统功能的用户总数量

PV/UV

  • PV:Page View的简写,即页面的浏览量或者点击量
  • UV:Unique Visitor的简写,即指系统的独立访客

点击率

每秒的页面点击数我们称为点击率(通常说的hit),该性能指标反映客户端每秒向服务端提交的请求数
在性能测试中,我们一般不发起静态请求(指静态资源的请求,比如JS、CSS、图片文件等),所以hit指的是动态请求

不发起静态请求是因为静态请求一般是可以走缓存,比如CDN等,很多静态请求一般都不需要经过应用服务器的处理,要么直接走CDN缓存,要么直接请求到Web服务器就被处理完成

吞吐量

吞吐量指系统在单位时间内处理客户端请求的数量,从不同的角度看,吞吐量的计算方式可以不一样:

  • 从业务角度:吞吐量可以用请求数/s、页面数/s等来进行衡量计算
  • 从网络角度:吞吐量可以用字节数/s来进行衡量计算
  • 从应用角度:吞吐量指标反映的是服务器成熟的压力,即系统的负载能力
    一个系统的吞吐量一般与一个请求处理对CPU的消耗、带宽的消耗、IO和内存资源的消耗情况等紧密相连

资源开销

每个请求或事务对系统资源部的消耗,用来衡量请求或者事务对资源的消耗程度,比如:

  • 对CPU的消耗可以用占用CPU的秒数或者核数来衡量
  • 对内存的消耗可以用内存使用率来衡量
  • 对IO的消耗可以用每秒读写磁盘的字节数来衡量

(四)性能测试的目标

一、了解系统的各项性能指标

通过性能压测来了解系统能承受多大的并发访问量、系统的平均响应时间是多少,系统的TPS是多少

二、发现系统中存在的性能问题

  • 系统中是否存在负载均衡不均的情况:

负载均衡不均衡一般指的是在并发的情况下,每台服务器接收的并发压力不均匀,从而导致部分服务器因为压力过大而出现性能急剧下降,以及部分服务器因为并发过小而出现资源浪费的情况

  • 系统中是否存在内存泄漏的情况:

内存泄漏指的是应用程序代码在每次执行完后,不会主动释放内存资源而导致内存使用一直增加,最终会使服务器物理内存全部耗光

系统中是否存在连接泄漏的问题:
连接泄漏种类非常广泛,可以是数据库连接泄漏、HTTP连接泄漏或者其他TCP/UDP连接泄漏等。除了系统实际需要情况建立长连接外,一般短连接都应该是用完就需要关闭和释放

  • 系统中是否存在线程安全的问题:

线程安全问题是高并发访问的多线程处理系统中经常出现的问题,如果系统中存在线程安全问题,就会出现多个线程先后更改数据,造成所得到的数据全部是脏数据,有时候甚至造成巨大的经济损失

  • 系统中是否存在死锁的问题:

死锁问题是多线程系统中经常会遇到的一个经典的问题,一般常见的有系统死锁、数据库死锁

  • 系统中是否存在网络架构或应用架构扩展性问题:

扩展性问题一般指的是性能指标无法满足预期的情况下,通过横向或者纵向扩展硬件资源后,系统性能指标无法按照一定的线性规律进行快速递增

三、解决性能压测中存在的问题和性别瓶颈

通过不断的性能调优,使得系统可以满足预期的性能指标

(五)性能需求分析

一、明确目标

熟悉被压测系统的基本业务流程,明确此处性能测试要达到的目标,与多方沟通找到业务需求的性能点
二、熟悉架构
熟悉系统的应用架构、技术架构、数据架构、部署架构等,找到与其他系统的交互流程,明确系统部署的硬件配置信息、软件配置信息,把对性能测试有重要影响的关键点明确列举出来,一般包括:

  • 调用关系

用户发起请求的顺序,请求之间的相互调用关系

  • 业务数据流走向

数据是如何流转的、经过了哪些应用服务、经过了哪些存储服务

  • 评估系统瓶颈

评估被压测系统可能存在的重点资源消耗,是I/O消耗型、CPU消耗型,还是内存消耗型,这样在压测时可以重点进行监控

  • 关注应用的部署架构

如果是集群部署,压测时需要关注应用的负载均衡转发是否均匀,每台应用服务器资源消耗是否大体一致

  • 了解并发架构

明确并发架构是采用多线程处理还是多进程处理,重点需要关注是否会死锁、数据是否一致、线程同步锁是否合理(锁的颗粒度不宜过大,过大可能会影响并发线程的处理)

三、系统上线的数据

明确系统上线后可能达到的最大并发用户数、用户期望的平均响应时间以及峰值时的业务吞吐量,并将这些信息转换成性能需求指标

(六)性能测试方案

需要按照性能需求分析的结果来制定性能测试方案,即按照什么样的思路和策略去测试、需要设计哪些测试场景以及测试场景执行的先后顺序、每个测试场景需要重点关注的性能点等,一般包括:

一、测试场景的设计

  • 单场景设计:单一业务流程的处理模式设计
  • 混合场景设计:多个业务流程同时混合处理模式的设计

二、定义事务

测试方案中需要明确定义好压测事务,方便分析响应时间(特别是在混合场景中,事务的定义可以方便分析每一个场景响应时间的消耗)

如果响应时间较长时,就可以对每一个事务进行分析,看哪个事务耗时最长

三、明确监控对象

针对每个场景,明确可能的性能瓶颈点(比如数据库查询、Web服务器服务转发、应用服务器等)、需要监控的对象(比如TPS、平均响应时间、点击率、并发连接数、CPU、内存、IO等)

四、定义测试策略

  • 明确性能测试的类型

需要进行哪些类型的性能测试,比如负载测试、压力测试、稳定性测试

  • 明确性能测试场景执行的顺序

一般是先执行单场景,后执行混合场景测试

  • 明确加压的方式

比如按照开始前5分钟,20个用户,然后每隔5分钟,增加20个用户来进行加压

五、性能测试工具的选取

  • 理解每种工具实现的原理

比如哪些工具适用于同步请求的压测,哪些工具适用于异步请求的压测

  • 明确压测时连接的类型

比如属于长连接还是短连接,一般连接多久能释放

  • 明确性能测试工具并发加压的方式

比如是多线程加压还是多进程加压,一般采用的是多线程加压

六、明确硬件和软件配置

  • 硬件配置一般包括

服务器CPU配置、内存配置、硬盘存储配置、集群环境下包括集群节点的数量配置等

  • 软件配置一般包括

操作系统配置、应用版本配置(特别是中间件、数据库组件等的版本,不同版本间性能可能不一样)

  • 参数配置一般包括

web中间件服务器的负载均衡、反向代理参数配置、数据库服务器参数配置等

七、网络配置

一般为了排除网络瓶颈,除非有特殊要求外,通常建议在局域网下进行性能测试

(七)性能分析调优思想

一、层层分析

分析分析指的是按照系统模型、系统架构以及调用链分层进行监控分析和问题排查

分层分析一般需要对系统的应用架构以及部署架构的层次非常熟悉,需要熟悉请求的处理链过程

分层分析一般需要对每一层建立checklist,然后按照每层checklist逐一进行分析
分层分析来排查问题的效率虽然较低,但是往往能发现更多的性能问题
分层分析可以自下而上,也可以自上而下

二、科学论证

科学论证指的是通过一定的假设和逻辑思维推理来分析性能,一般包括发现问题、问题假设、预测、试验论证、分析这5个步骤

  • 发现问题:

通过性能采集和监控,发现性能瓶颈或性能问题,比如并发用户数增大后TPS并不增加,每台应用服务器的CPU消耗相差特别大等

  • 问题假设:

根据自己的经验判断,假设是某个因素导致了出现瓶颈和问题

  • 预测:

根据问题假设,预测可能出现的一些现象或特征

  • 试验论证:

根据预测,去检查预期可能出现的现象或特赠

  • 分析:

根据获取到的实际现象或特征进行分析,判断假设是否正确,如果不正确则重新按照这个流程进行分析论证

三、问题追溯与归纳总结

问题追溯指的是根据问题去追溯最近系统或者环境发生的变化

归纳总结指根据经验的总结,在出现某些性能瓶颈或者性能问题时,根据以往总结的原因逐一排查

(八)性能调优模型

性能调优模型归纳:

在这里插入图片描述
一、网络分发
网络分发是高速发展的互联网时代,常用的降低网络拥塞,快速响应用户请求的一种技术
常用的就是网络分发CDN,内容网络分发,依靠部署在世界各地的边缘服务器,通过中心平台的负载均衡,源服务器内容分发,调度等功能模块,使世界各地的用户就近获取所需服务,而不是用户每次到源服务器获取响应
源服务器内容更新,会被同步到全网各个网络节点,同一个资源有一个人访问会被缓存同步到最近边缘节点,该地区的其他人访问该资源就会从CDN缓存服务器获取,降低源服务器压力,提高网站性能

二、web服务

web服务器就是用来部署Web服务,用来负责请求的响应和分发以及静态资源的处理

三、web cache

web服务器的缓存,用来临时缓存Html,Css,图像等静态资源文件

四、应用程序服务

应用程序部署在应用服务器上,对外提供服务的核心程序或服务,应用服务器就是Tomcat,WildFly,普通的Java应用等,应用程序服务就是提供用户可以访问的服务

五、cache

应用缓存, 程序层的缓存服务,常见的有Redis,MemCached等,缓存可以大量提高高并发的性能,是分布式应用架构经常使用的技术

六、外部系统

大部分系统都需要请求外部系统或者内部多模块交互或许数据信息,这需要创建Http连接,消耗服务器资源,也是性能分析需要重点关注的

七、数据库

数据库最有可能是系统性能的瓶颈,查询慢或锁线程操作数据库死锁等

(九)性能调优技术

一、缓存调优

为了提高用户访问请求的响应时间,缓存的使用已经成为大型系统使用的一个关键技术

缓存按照存放地点的不同,可以分为用户端缓存和服务端缓存
在这里插入图片描述

缓存调优的关键点:

  • 如何让缓存的命中率更高?
  • 如何注意防止缓存穿透?
  • 如何控制好缓存的失效时间?
  • 如何做好缓存的监控分析?(比如慢日志分析、连接数监控、内存使用监控等)
  • 如何防止缓存雪崩?

缓存雪崩指的是服务器在出现断电等极端异常情况后,缓存中的数据全部丢失,导致大量的请求全部需要从数据库中直接获取数据,从而使数据库压力过大造成数据库崩溃。防止雪崩需要注意:

要处理好缓存数据全部丢失后,如何能快速把数据重新加载到缓存中 缓存数据的分布式冗余备份,当出现数据丢失时,可以迅速切换使用备份数据

二、同步转异步推送

同步指的是系统收到一个请求后,在该请求没有处理完成时,就一直不返回响应结果,直到处理完成后才返回响应结果

与同步相比,异步指的是系统收到一个请求后,立即把请求接收成功返回给请求调用方,在请求处理完成

三、拆分

拆分指的是系统中的复杂业务调用拆分为多个简单的应用,一般遵循以下原则:

  1. 对于高并发的业务请求调用都单独拆分为单个的子系统应用
  2. 对于并发访问量接近的业务,可以按照产品业务进行拆分,相同的业务类型是一个后台服务

注意:

拆分微服务需要谨慎考虑,拆分出来的服务之间涉及数据交换,内部通信,互相依赖,会增加运维成本和开发维护成本,拆分的不可太细,还要考虑团队组织结构和管理模式等

在这里插入图片描述

将高并发业务用子系统单独处理,相近的业务可以合并,提高系统的并发能力,这么拆分带来的好处是高并发业务不会对低并发业务的性能造成影响,而且系统在硬件扩展时,可以有针对性的进行扩展,避免资源浪费
同时系统也需要一个路由服务,作为统一的入口,区分业务的不同,将业务请求分发到各个子系统中。路由服务还可以实现统一的业务鉴权服务和统一的请求、响应处理或业务的统计等功能,避免子系统做公共处理,让子系统专注做业务强相关的事,提高子系统的处理能力

四、任务分解与并行计算

任务分解与并行计算指的是将一个任务分为多个子任务,然后将多个子任务并行进行计算处理,最后只需要将并行计算结果合并到一起返回即可,这样通过并行计算方式增加处理能力
采用多线程的方式,实现并行计算,提高并发处理能力,但是要注意线程共享数据的线程安全问题

任务分解方式1:

在这里插入图片描述
任务分解2:
在这里插入图片描述
五、索引与分库分表
索引指应用程序在查询时,尽量使用数据库索引查询,数据库表在创建时也尽量对查询条件字段建立合适的索引
强调合适的索引,因为如果索引建立不合适,不仅对查询效率没有任何帮助,反而会使数据库在插入时变得更慢,建立了索引,插入数据时数据库会自动更新索引,加大了数据库插入时的资源消耗

栗子:

数据库的一个字段status,status的值只有1、2、3,如果对status建立索引,对查询效率没有任何帮助,因为这个值只有三个值,取值范围太少,建立索引后根据status去检索时,需要扫描对数据量还是非常大

正确对索引可以很好的提升查询效率,但是如果一个表的数据量非常庞大,达到亿万级别,此时索引查询也是很慢,并且插入数据也很慢,这时候需要进行分表或者分库

分库一般是指一个数据库的存储量已经很大,查询和插入时I/O的消耗非常大,此时需要将数据库拆分成两个库,以减轻读写时I/O的压力

常见的分库分表方式如下 :

  • 按照冷热数据分离方式

使用频率高的数据称为热数据,查询频率较低的数据被称为冷数据,冷热数据分离后,热数据单独存储,这样数据量就会降下来,查询的性能自然提升了,而且还可以更方便的单独针对热数据进行I/O性能调优

  • 按照时间维度的方式

实时数据和历史数据分库分表,可以按照年/月时间区间分库分表,尽可能减少每个库表中的数据量

  • 按照数据库操作方式

数据库读写分离,将查询操作和写操作分离,读写分离就是在主服务器上修改,数据会同步到从服务器,从服务器只能提供读取数据,不能写入,实现备份的同时也实现了数据库性能的优化,以及提升了服务器安全

数据库分库分表后带来的另一个好处 : 如果单次查询时需要查询多个分表, 此时就可以通过多线程并行方式去查询多个分表,最后合并每个分表的查询结果即可,这样可以使得查询效率更高

转载地址:https://lluozh.blog.csdn.net/article/details/111602219 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:【软件性能测试与调优实践】服务性能监控与分析
下一篇:【SpringBoot】AOP应用实例

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年05月03日 19时26分25秒