性能测试体系建设演进之路

时间:2024-01-26 21:40:31

题记

今年是我个人从事软件测试工作的第六个年头,职业生涯至今经历了功能-接口-自动化-性能测试岗位的变迁。

18年下半年开始以团队owner的角色进行工作开展,不过当时团队技术体系建设已经步入正轨,对我个人而言,并没有太多沉淀。

19年跳槽后,有幸从零开始主导我司的性能测试体系建设工作,个人之前的很多想法得以落地实现。

这也许是除了薪资之外,对我个人而言获得的最大成就感。。。

 

导图

image.png

 

演进

基础建设

1、文档建设

前段时间知乎回答了一个问题:做技术人是不是都反感写文字类的东西,比如需求文档,需求分析等等?之前的博客也写过类似的内容:性能测试从零开始实施指南——文档建设篇

我个人认为无论是作为个人学习笔记抑或一个Team的累积沉淀,文档建设的工作必不可少,而且是重中之重。原因如下:

1)降低“口头说明”带来的风险;

2)文档是很重要的记录和交流介质;

3)便于事前、事中、事后快速回溯追踪;

4)降低工作交接、沟通的成本,提高效率;

5)文档是一次梳理思路,review的方式;

6)文档是很重要的工作产出,自我价值诉求的重要手段(KPI);

当然,现在有很多在线协同文档工具,如confluence、语雀(参考-工具汇总)。我司性能团队文档类目如下:

image.png

2、资源管理

这里的资源主要指压测资源,包含如下几项:

1)压测机

2)压测场景

3)压测脚本

4)压测数据

无论是平台化还是基础的命令执行,其中要考虑的因素还是很多的,比如:

脚本命名规则:以接口名命名,见名知意;

文件命名规则:以参数类型、字段名命名;

权限管理:性能测试同学可以赋予root/s-user权限;开发&业务测试同学可以赋予ops/onlyread权限;

路径管理:按照服务器的访问权限&路径命名,比如:

       压测脚本路径:ops/perftest/script/transcation/order/ordercreate.jmx

       压测数据路径:ops/perftest/data/transcation/order/productId.csv

PS:如上命名规则和权限路径,以jmeter命令行启动场景为准,平台化可通过配置文件统一自定义。

3、环境建设

我个人强烈建议有一套独立的压测环境,这样既能做到和业务测试互不干扰,压测的结果相对来说也更贴近真实的场景。

考虑到成本和维护等因素,压测环境建议按照具体情况来配置,主要遵循如下几条原则:

1)机器配置和生产保持一致;

2)机器数量和生产进行等比缩容(可以同配置最小化,即1台机器1个服务);

3)网关和注册中心&配置中心可以集群部署(按照流量大小);

4)支持自动扩容、监控告警等功能(需要基础技术建设到一定程度,比如:发布&监控平台支持)

PS:上述原则,基于微服务架构!

4、技术选型

技术选型主要考虑如下几个方面:

1)压测工具:接入成本、学习成本,重点是快速产出有效直观的价值!

2)监控工具:监控工具要考虑到性能损耗、接入难度、全面性、易用性;

3)数据工具:包括造数工具、数据存储、解析等方面;

4)分析工具:主要指的是问题分析工具,比如JDK自带的JVM Profiler;

 

规范制定

技术体系建设中,规范的重要性不言而喻。在性能测试中,比较重要的有如下几条规范:

1、需求发起

性能是一种需求!需求从何而来,如何发起,准入准出条件,必须优先界定好。思维导图:

image.png

2、需求评估

在性能需求评估中,主要考虑如下几点:

1)可行性(必要性)分析;

2)收益率评估(投入/产出-ROI);

3)约定关键时间节点,如提测、deadline;

4)统一重要指标口径,明确预期指标(业务&技术);

3、资源排期

这里的资源主要指人力资源、时间窗口以及机器资源,对于一个team来说,资源排期很重要!

4、指标度量

这里的指标并非压测数据指标,而是从部门/Team角度长期来看,需要考虑的指标,主要参考如下几点:

1)成本:测试前后,机器成本降低了多少;

2)数据:每迭代/版本,服务/链路性能提升占比;

3)效率:每个阶段,准备/部署/测试耗时降低了多少;

4)输出:团队/部门内部技术分享、性能宣讲、质量意识提升比;

5)质量:每统计区间,线上服务可用性/稳定性提升比、故障率下降比

6)赋能:每月/季度,业务测试团队性能测试工时/需求接入/技能提升占比

5、测试方案

测试方案的规范,可以视公司研发文化、team大小、具体情况来制定。当然,制定一个规范模板还是很有必要的,这样不仅能对工作给出一定的指导方向,还便于其他干系人能快速了解。

参考:简易性能测试方案模板

性能测试方案模板.docx

6、测试报告

同测试方案一样,测试报告的规范模板也是很有必要的,同样可以对工作给出指导方向。

参考:简易性能测试报告模板

性能测试报告模板.docx

 

需求周期

1、调研评估

接触了很多做性能测试的同学,聊下来,发现部分同学对性能需求的可行性评估,依然不太明白为什么这么做。如上文所说,在性能需求调研评估过程中,要注意的几点分别如下:

1)可行性分析:即业务场景、该场景的技术实现方案、用户特征等,是否有必要开展性能测试;

推荐阅读:认清性能问题(Thinking Clearly about Performance)

2)收益率评估(ROI):开展性能测试的成本,包括时间、人力、机器环境成本,以及技术改造成本;

3)约定关键时间节点,如提测、deadline:这样做的好处是能根据测试时间窗口更好的评估测试工作的安排,知道什么时间做什么,区分优先级很重要。

4)统一指标口径,明确预期指标:比如双11大促,技术指标包括:日常线上峰值流量、机器负载、预估流量递增比率、扩容速率、consumer group、告警阈值等;

   而业务指标包括:预计GVM、活动场次时间、优惠券类型数量、订单量等指标。明确这些数据后,才能更好的评估需求,进行压测方案设计。

2、需求排期

需求排期的重要性不言而喻。如何在有限的资源下尽可能提高需求的吞吐量,除了个人工作效率、团队协同能力之外,良好的资源评估和任务分配是很重要的影响因素。

3、准入准出

无论是过早还是过晚的考虑性能问题,都会是一场灾难!

过早考虑不确定性较多,太晚的话,优化成本及风险又太高,因此,选择合适的时机开始,是很重要的。

性能测试切入时机,是个玄学,需要考虑需求类型、具体场景、资源、时间、优先级等很多因素。但一般来说,还是有适合大多数场景的参考原则,列举几项供参考:

1)普适性原则-功能测试提测阶段切入;

2)特殊性原则-电商双11,最少提前2个月准备;

3)迭代性原则-二轮测试开始时切入;

4)新服务原则-prd&技术review阶段切入;

 

数据管理

数据管理是性能测试中很重要的一环,无论是数据量级、分布方式、是否缓存、缓存大小还是热点数据,都是需要考虑的地方。

还有一点经常被忽略的,是数据多样性引起的覆盖率问题。性能测试中,主要有如下几种类型:

1、基础数据

对于性能测试来说,基础数据一般指的是支撑业务流程正常运行所必备的数据,需要考虑如下几个方面:

1)数据量级:根据环境具体配置信息,保证数据量级和生产环境等比例,是很有必要的事情;

2)数据脱敏:从经验来说,基础数据的量级一般较大,常见的准备方式都是copy生产数据并进行脱敏;

2、测试数据

测试数据是为了满足被测业务场景的链路而所需的数据,在具体的压测准备阶段,需要根据被测链路,针对性的准备测试数据,保证场景的正常执行;

3、唯一性数据

某些比较特殊的被测场景,所需的数据是具有唯一属性的,或者一次性使用的特性。

从经验来说,这类数据,建议通过走正常的业务逻辑去生成,可以根据所需数据量大小来准备。

4、参数化数据

这类数据一般是具有可复用性的,比如productId/userId...,建议提前了解整体的业务和技术类型,准备一批量级较大的数据,避免重复工作。

 

问题追踪

1、问题记录

针对压测过程中发现的问题进行分类记录汇总,是很重要的一件事。优点如下:

1)问题追溯

2)工作产出

3)输出规范手册

PS:性能缺陷分类参考

缺陷类型 缺陷描述
硬件 磁盘空间
CPU
IO读写速率
内存
网络 带宽
网络波动
CDN
延时
丢包
应用 JVM
代码逻辑
配置 JDK版本
底层配置
参数配置
数据库 索引
表空间
慢SQL
数据量
中间件 超时
线程池
缓存策略
最大连接数
通信实现方式
负载均衡

2、生命周期

性能问题的生命周期,和功能BUG一样,这点技术同学应该都懂。

3、方法输出

影响性能的因素有很多,但绝大多数的性能问题都是由于配置、参数、代码逻辑的问题导致。

通过对性能问题的分类记录汇总追溯,可以总结出一些比较通用的参考规范,类似《阿里巴巴java开发手册》。

常见影响性能的因素及优化建议如下:

1)日志打印:降低日志输出level,减少IO消耗;

        日志打印建议移除json序列化操作;

        关闭状态机内相关日志,添加开关,大促时关闭;

        出参过多情况下,封装处理,只打印需要的核心参数;

        避免统一日志处理的apo拦截,建议移除所有主动拦截,需要的地方添加注解;

2)缓存使用:针对不易发生变动/变动影响较小的调用添加缓存/数据快照;

3)调用方式:对于一些聚合类的接口调用,建议串行改并行/异步调用;

4)线程配置:隔离各接口使用的线程池,防止长短尾拖垮线程池;

        为了防止网络抖动,建议线程数按照(CPU可用核心数/(1-阻塞系数)*2)配置。

        worker-threads、maxConnections、ConnectTimeout、ReadTimeout等参数无需过高;

5)重复调用:微服务间的调用存在方法调用冗余情况,应尽量避免;

6)等待队列:根据等待队列长度算法来说,建议队列长度根据可接受的最长时间来配置,比如:

       接受最长时间500ms,超过500ms还不能处理丢弃。已知正常rt25,每个线程500ms可以处理20个等待队列内的请求,

       假若有16个线程,所以等待队列长度设置为320。队列过长无意义,无法新增非核心线程,且持续恶化处理速度。

 

监控体系

监控体系的构建,是一个长期迭代的过程,很考验基础技术建设的能力和程度。

除了压测本身所需的指标监控,还需要对被测服务的资源耗用(基础监控)、链路调用关系(链路监控)以及各种中间件进行监控。

1、压测监控

基于jmeter+influxdb+grafana搭建的压测监控大盘:

image.png

2、基础监控

基于Prometheus技术体系搭建的基础指标监控大盘:

image.png

3、链路监控

目前业界内链路监控工具还是蛮多的,而且开源的也不少,足以满足日常所需。比如Cat、Jaeger、Zipkin、Pinpoint、Skywalking等。

下图为Jaeger的链路追踪界面:

image.png

4、中间件监控

中间件监控,涉及的组件较多,比如redis/MQ/Kafka/DB等,上面提到的链路监控工具,实际上对中间件的监控支持还算不错,当然,各有优劣。

需要哪些指标,告警阈值如何设置,还是按需所配吧。

image.png

 

报表输出

报表对于一个team来说是很重要的工作量化产出!

1、轮次小结

一般来说,性能测试要执行多轮的测试验证,针对每轮结果进行直观的比较验证,无论从效率还是信息同步方面,都是很有帮助的。

2、数据归档

这里的数据归档,包含需求吞吐量、完成质量、遗留问题、压测结果等很多数据。

我们目前的做法及规划如下:

1)需求/问题归档:写入mysql,通过定时job扫描,并定期拉取数据进行不同维度的聚合计算,CC干系人。

2)压测数据归档:写入Influxdb,并提供查询API给到度量平台来聚合数据,做其他维度的报表展现。

3、性能基线

属性

说明

目的

作为衡量版本迭代的一个质量维度系数,更全面的衡量每版本的交付质量

衡量维度

1)每版本性能基准;2)长期性能变化趋势(季度/年度)

执行方式

每版本迭代对核心链路进行覆盖执行,采用回归测试策略

执行时间

二轮回归开始→发布预发之前

性能基线的建立,有以下几点需要注意:

1)定义基准:包括术语、维度、范围、指标等信息的统一说明;

2)基准数值:个人建议可接受降幅原则上≤5%;

3)跟踪方式:性能变化的跟踪方式,和上述的衡量维度类似,分短期和长期,时间区间可自定义;

4)实施说明:包含执行的时间、范围、具体方式、准入准出条件,该任务最好具体到人;

5)前置条件:核心链路梳理、初始版本基准数值确认、环境/压测机/权限分配/路径/脚本/数据;

PS:如何追踪、如何统计并聚合计算,根据team情况和具体情形自行确定!

4、容量规划

容量规划是一个长期建设的过程,目前我司也是规划中,具体如何开展,什么时候开展,有哪些方法论,业内目前并没有一个普适性的方法论。

可以参考我之前的一篇博客:浅谈容量测试与容量规划

 

赋能开源

我个人认为,性能是一个团队所必需具备的能力和特质,并不是少数专职性能测试同学才能做得事情。

在基础的技术建设和性能测试成熟度到一定程度时,可将部分压测相关工作&权限赋予业务测试和业务研发团队,这样不仅有助于工作上互相了解,

更能提高整个团队的能力,性能测试同学也可以抽出更多时间在稳定性保障工作上,而不是写个脚本压测下,就完事的重复工作。

更多阅读:当我们讨论性能测试时,我们在说什么?

 

团队沉淀

要想不断提高团队的技术、沟通协同、解决问题能力,团队升级是需要时刻考虑的。

只有不断提升团队整体的能力,个人的能力才会更快的提升。一般来说,常见的方式有如下几种:

1)技术累积:前面说的文档建设就是个很好的方式,还可以输出技术白皮书等内容;

2)内部培训:建议定期开展,一般每个月固定开展一次,包括技术、业务、经验和教训;

3)团队分享:指的是包含整个研发部门甚至整个公司的跨团队分享,还是建议积极参与;

4)公开沙龙:当团队规模,技术累积等到了一定程度,可以对外举行技术沙龙,进一步提升技术影响力的同时,也是一个很好的锻炼个人能力的方式。有输入有输出,才能有所得

5)技术大会:每年都有很多的业内技术大会,可以挑选具有一定影响力和知名的行业大会,在团队里挑选部分优秀的同事参加,然后分享,这也是一个促进团队凝聚力的方式。