导语
软件行业飞速发展,时下大数据规模宏盛,人工智能兴起,好不热闹。SDLC 从瀑布到敏捷再到精益化的 devops,持续集成广泛使用。作为测试从业者,迎潮而上,势必要更广泛的渗透到项目始终,传统的黑盒、白盒、性能、自动化、安全方向分类变得模糊,优秀的测试人员无时不刻在项目各阶段不遗余力地集成质量工作,并保持井井有条,不失优雅。本文将讨论性能测试相关内容。
性能测试是什么?
在软件工程中,性能测试是一种测试实践,用于确定系统在特定工作负载下的响应性和稳定性方面的表现。它还可用于调查,测量或验证系统的其他质量属性,例如可伸缩性可靠性和资源使用。
什么时候做性能测试?
软件性能^1是软件的一种非功能特性,它关注的不是软件是否能够完成特定的功能,而是在完成该功能时展示出来的及时性。
所以说,普遍意义上的性能测试发生在功能测试完成(功能能够正确执行)之后。
一个复杂系统几轮测试至功能稳定,性能测试一跑,发现和线上期望值差别很大,这时候和开发一起调优,如果只是简单的配置优化和局部代码改改就解决了问题固然开心,但万一发现是架构缺陷,这时候调整无异于牵一发而动全身。
我们要做的更好,就应该在项目早期纳入性能集成:
- 需求阶段,评审出性能需求(性能规格),比如C端服务场景,至少应该有个用户量和数据量的概念;
- 设计阶段,对引入的技术栈有基本的性能考量:关注扩展性,关注数据库设计,对引入的外部开源组件查阅或产出 benchmark 报告;
- 编码阶段,为开发指定一个良好易用的支持并发的单元测试框架(如testng),开发在一些可能发生性能问题的逻辑段or算法中,编写压力单元测试集成。更好的方式是组织代码审查 codereview(不必要、低效的锁、不必要的安全线程设计、糟糕的数据结构、冗余的网络访问…),坚持每天静态代码扫描构建(如sonar),其定义的常见性能缺陷规则在发现疏忽导致的一些低级的性能缺陷很有帮助。
这样一来,再进入普遍意义的性能测试阶段过程,性能不可控风险已经最低,可以把更多精力放在参数调优和容量规划上了。
性能测试目标?
- 验证软件在特点场景下的性能表现,并枚举一些量化的指标;如当下互联网在线服务领域广泛定义的SLA(服务等级协议),并给出相应的SLI(Service Level Indicator 关键量化指标);
- 当1未满足期望的情况下进行调优并使满足(当然相应的量化指标并不总是存在,当然没有人来表达给定用户群的最大可接受响应时间等等的时候,性能测试经常用作性能配置文件调优过程);
- 在1,2基础上,验证软件or硬件扩展情况下的性能增长表现,并给出合适的容量规划满足生产的服务需求,最终部署到生产环境中,并展开良好的监控经验以持续规划。
性能测试工作?
确定测试目标
制定性能测试工程的截止目标,如上所说,这往往是多样性的。例如:量化业务的吞吐量指标(可以使用28原则,指80%的业务量在20%的时间里完成)。
设计测试场景
- 环境选定:性能测试团队通常不在开发/测试环境中执行性能测试,而是在专门的预部署环境中执行,该环境配置尽可能接近计划的生产环境,这通常包含硬件,网络,操作系统,数据库,基础件的约定;
- 事务:定义关键业务的工作流程 ,事务即关键业务可以是收入价值较高的、被其他项目频繁依赖的、已识别的可能影响系统性能的高风险项等等,这通常是协同性能测试需求方一起评审敲定的;
- 由简入繁:通常来说,测试场景应遵循由简到繁,先从单一事务,单一维度去分类执行性能测试,然后再过渡到混合的接近真实线上场景事务比率,甚至注入一定数量的随机故障观察系统表现。
编写性能测试脚本
根据设计的测试场景访问形式配合适当的负载工具完成测试脚本的编写/录制。常见如测试web网站可以通过jmeter http 代理服务录制网站业务操作并回放;
分类执行性能测试
下图为性能测试经典负载模型,我们可以按阶段为性能测试分类:
负载测试
负载测试(0-b)是最简单的性能测试形式。通常通过不断对系统添加压力进行负载测试以了解系统在特定预期负载下的行为,直到系统出现某些资源耗尽,例如CPU或者网络带宽。压力测试
压力测试(a-b)通常用于理解系统内容量的上限。进行此类测试是为了确定系统在极端负载方面的稳健性,并帮助应用程序管理员确定如果当前负载远高于预期最大值,系统是否能够充分运行,通常情况下会先进行负载测试,再根据负载测试的结果,确定压力测试的方案。
浸泡\耐久测试
(80%a)耐久测试通常在系统资源尚未耗尽的健康范围内让应用承受持续的大量负载,并监视检测潜在的泄漏。确保在一段长时间(N*24h)的持续活动之后的吞吐量或响应时间与测试开始时一样好或更好。
通常来说,上述过程已经覆盖大部分的性能测试需求,更多分类^2可以了解下:
尖峰测试
通过突然增加或减少由大量用户产生的负载并观察系统的行为来完成尖峰测试。目标是确定性能是否会受损,系统是否会失败,是否能够处理负载的显着变化。配置测试
不是从负载角度测试性能,而是创建测试以确定系统组件的配置更改对系统性能和行为的影响。一个常见的例子是尝试不同的负载平衡方法。互联网测试
在真实环境通过一定规模的负载生成器(无论是物理机还是云虚拟机)对生产环境进行性能测试, Facebook, Google and Wikipedia这些全球公司经常这么干 ,这是一种相对较新的性能测试形式。这些测试通常需要大量的准备和监控才能成功执行。
获取性能数据
确保部署和配置性能监视软件来收集所有的关键指标,并可以跟踪一段时间内的趋势,生成监控报告。这一部分同时适用于验证系统已有的监控功能和帮助监控系统的规划。在互联网在线服务,基于服务等级的监控子系统建设往往是必须的。
定位并修复性能问题
在获取的监控结果不符合测试预期的情况下,定位问题并使达成的过程。有时候一个项目没有很好的实践性能集成,导致有些测试无法调整到达成预期,则有必要终止性能测试将系统的各部分返回到开发中进行重构。
基于目标的总结;
总结性能测试结果和生产环境实施,这包括实践性能测试环境中的最优配置,部署持续的性能监视和容量规划方案。
常见的性能关注指标有哪些?
响应&稳定性
并发用户
顾名思义,这里是系统在任何给定时刻都应支持的最大并发系统用户数。
吞吐量(Hits per second, Request per seconds, Transaction per seconds)
后端服务往往没有用户的概念,那么性能目标往往基于最大吞吐量或事务速率。
响应时间(response time)
指的是一个系统节点响应另一个系统节点的请求所花费的时间 ,如从浏览器客户端到Web服务器的HTTP GET请求。
通常表现形式可以是平均值average,中位值median,百分比分布percentile,不过平均值 or 中位线都只能是一维世界,百分比分布可以更好的图像化(更形象的,更细粒度的)反馈目前系统的响应时间状况。
响应成功率
测试事务断言成功率、超时错误率
可伸缩性
通过增减软件&硬件部署规模达到服务的扩容or缩容,良好的软件设计应该具备好的伸缩性,比如分布式的设计,但是通常来说,添加更多的硬件会导致收益递减;
- 可靠性
理想系统在任何给定时刻都应该具备高可靠性,比如长时间的不停机运行,突然的峰值交易,部分硬件故障;
资源
服务器:Memory, cache, process, processor, disk and network、open files
网络:Bytes, packets, segments, frames received and sent per sec, Bytes
数据库:缓存命中、索引、连接池、锁
应用:日志、线程池、内存回收
性能测试有哪些好的工具?
负载工具
开源名牌:Apache JMeter、locust
老牌商业:HP LoadRunner
互联网基于云的在线服务方案:例如loadview-testing 。区别于传统性能测试所有的虚拟用户都来自自己的服务器(这代表测试是在理想条件下进行的 ,甚至不会穿越自己的防火墙)云压测体验往往是端对端的,多地域的,能更好的还原线上真实压力行为,但是显然成本高了,且监控相对复杂,不过个人认为这不影响它成为一种趋势。
服务器资源监控图表工具
小而美:nmon、Jmeter Servers Performance Monitoring
分布式全能:Zabbix
时下火热的云监控:datadog(提供了主流云服务和流行开源项目监控模板整合)
调优工具
JS:JSLitmus、jsperf、chrome profile
java:jvisualvm 、JProfiler、Eclipse Memory Analyze(MAT)
linux:直接引用系统性能大神Brendan Gregg 的总结和实践perf-tools
待续…