性能测试是通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试。
性能测试的目标
:
- 评估系统的能力,测试中得到的负荷和响应时间数据可以被用于验证所计划的模型的能力,并帮助作出决策。
- 识别体系中的弱点:受控的负荷可以被增加到一个极端的水平,并突破它,从而修复体系的瓶颈或薄弱的地方。
- 系统调优:重复运行测试,验证调整系统的活动得到了预期的结果,从而改进性能。
- 检测软件中的问题:长时间的测试执行可导致程序发生由于内存泄露引起的失败,揭示程序中的隐含的问题或冲突。
- 验证稳定性(resilience)可靠性(reliability):在一个生产负荷下执行测试一定的时间是评估系统稳定性和可靠性是否满足要求的唯一方法。
名称 | 内容 |
---|---|
压力测试 | 评估应用程序在峰值负载和正常情况下的行为 |
并发测试 | 并发访问同一个应用、同一个模块或者数据记录时是否存在死锁或其者他性能问题 |
负载测试 | 负载测试的目的是通过不断地、稳定地增加系统的负载来测试系统,直到达到阈值 |
配置测试 | 调整软硬件的配置,了解其对系统的性能影响程度,从而找到系统最优配置 |
软件工程中,应用程序或者系统的容量通常会因为单个组件的限制,出现瓶颈,瓶颈在事物路径的所在部分中具有最低的吞吐量。系统设计人员尝试避免瓶颈,并直接努力查找和调整现有瓶颈。可能的瓶颈:处理器,通信链路,磁盘 IO 等。
- 硬件
缺陷 | 描述 |
---|---|
磁盘 | 磁盘空间不足,磁盘读写慢 |
CPU | 占用过高,程序运行变慢 |
IO 读写速率 | 数据处理时的 I/O 速率,页交换等 |
内存 | 占用过高,程序运行变慢 |
- 网络
缺陷 | 描述 |
---|---|
带宽 | 网络资源竞争,超时 |
延时 | 物理层面的延时,无法避免,但可减轻 |
丢包 | 硬件故障,线路故障,网络拥塞 |
- 应用
缺陷 | 描述 |
---|---|
JVM | 1.堆内存分配:一般不超过系统内存的 25% 2.垃圾回收算法:根据具体情况选择合适的垃圾回收策略 3.OOM:内存泄露,GC不完整,内存耗尽 |
代码层 | 不合理的线程引用和内存分配 |
JDK 版本 | 尽可能和生产环境版本一致 |
底层配置 | OS,服务器硬件的配置不合理,带来的性能瓶颈 |
参数配置 | 系统架构设计,不同参数配置带来的性能瓶颈 |
- 数据库
缺陷 | 描述 |
---|---|
索引 | 合适的索引,减少磁盘 IO 与数据库执行时间 |
锁 | 并发场景下的表锁,行锁,页锁 |
表空间 | 不合理的表结构设计 |
慢 SQL | 1.未命中索引 2.select * 3.like % 4.使用大事务的 SQL |
数据量 | 数据量不同,性能差异大 |
- 中间件
缺陷 | 描述 |
---|---|
超时 | 设置合理的超时时间,需要配置测试来设定 |
线程池 | 太小,容易被使用完 太大,造成浪费,配置测试来设定 |
缓存策略 | 缓存失效,缓存穿透 |
最大连接数 | 连接数少导致队列等待、超时,多则浪费资源 |
通信方式 | 同步或者异步 |
负载均衡 | 集群,负载均衡策略选择 |
- 资源指标
- CPU使用率:指用户进程与系统进程消耗的CPU时间百分比,长时间情况下,一般可接受上限不超过85%。 - 内存利用率:内存利用率=(1-空闲内存/总内存大小)*100%,一般至少有10%可用内存,内存使用率可接受上限为85%。 - 磁盘I/O: 磁盘主要用于存取数据,因此当说到IO操作的时候,就会存在两种相对应的操作,存数据的时候对应的是写IO操作,取数据的时候对应的是是读IO操作,一般使用% Disk Time(磁盘用于读写操作所占用的时间百分比)度量磁盘读写性能。 - 网络带宽:一般使用计数器Bytes Total/sec来度量,Bytes Total/sec表示为发送和接收字节的速率,包括帧字符在内。判断网络连接速度是否是瓶颈,可以用该计数器的值和目前网络的带宽比较。
- 系统指标
- 并发用户数:某一物理时刻同时向系统提交请求的用户数。
- 在线用户数:某段时间内访问系统的用户数,这些用户并不一定同时向系统提交请求。
- 平均响应时间:系统处理事务的响应时间的平均值。事务的响应时间是从客户端提交访问请求到客户端接收到服务器响应所消耗的时间
- 90%响应时间:所有样本的响应时间按照从小到大排列,取全部的第90%位的数值作为响应时间,该值在Jmeter也是一种标准统计指标(This is a standard statistical measure)。如果面试问到使用平均还是90%,尽可能答90%
,或者把两者都说出来并带出两者时间的差异
- 事务成功率:性能测试中,定义事务用于度量一个或者多个业务流程的性能指标,如用户登录、保存订单、提交订单操作均可定义为事务
- 超时错误率:主要指事务由于超时或系统内部其它错误导致失败占总事务的比率
- 吞吐率:样本数量除以计数时间;三种计数方式:页面/s、请求数/s、Bytes/s,不同场景采取方式不同,或者同时使用多个
并发用户点击量:通过工具模拟用户的操作来实现多个用户同时使用系统的场景。
通过Jmeter添加多线程,然后线程数设置>1,再添加该任务对应的请求、断言等,启动即可。
性能测试与其他测试活动一样,都是需要需求的提出与相应的评审活动的。
需求阶段
- 提出需求:产品人员,开发人员,测试人员,运维人员都可以提出
- 需求评审:这一步是出具测试计划的关键
- 需求调研:主要是对测试实施细节沟通和确认
在需求阶段需要评估该性能需求可行性,资源调配,细节再次确认。再三确认可行后,便是进入性能测试的号角。
结束标志:测试场景测试完毕、发现的问题已全部修复、结果达到预期、满足上线要求,并且出具对应的测试报告。
- 根据压测场景:根据压测场景是什么来选择。如果说是一次性单接口的场景就可以使用 AB。如果说是复杂事物多接口需要业务场景的话,就会选择 JMeter 这类工具可以构造丰富的场景能满足需求。
- 需要提供多大压力:是1000 QPS还是万级以上的。压力很大的话就要考虑压力测试工具是否支持分布式,能否快速扩展 agent。对于 JMeter 来讲就很好的支持了。
- 周期性需求:业务可能频繁上线,服务随时变动。可能会有一个周期性需求,按月巡检。需要一个场景文件,可以去做数据驱动,实时跟进数据改变。最后希望结果落库。
- 二次开发需求:JMeter 开源插件化思想,支持 Thrift,Dubbo 等多种协议。可以快速平台化。
- 问题支持:是否具备完善的文档支持,是否具备强大的开放社区,是否已广泛使用,工具成熟度等,有问题的时候能够快速获得答案。
工作内容 | 描述 |
---|---|
环境准备 | 运维提供适当的物理服务器或者虚拟机环境 |
应用部署 | 开发提供无明显功能缺陷的代码分支,运维帮忙部署到对应的测试服务器 |
数据准备 | 铺底数据:作为基础数据,模拟真实环境数据量 测试数据:用来发起并发的数据,可以事先准备或者动态生成 参数化数据:数据多样化,覆盖尽可能多的业务场景 |
脚本开发 | 针对性能测试工具进行对应的脚本开发,覆盖对应的测试场景 |
压测执行 | 不断执行压测脚本,以及脚本调整,改进测试结果 |
服务监控 | 狭义:单应用的监控,接口性能和错误监控,分布式调用链接追踪,其他用户诊断(内存,线程)的监控信息 广义:APP端监控,网页端监控,容器/服务器监控,其他中间件、数据库层面的监控 |
瓶颈定位 | 对日志,监控数据进行分析,定位瓶颈并做出优化 |
优化验证 | 对优化的软件再次执行压测,验证问题是否已经得到解决或者性能得到提升,标准是需求评审阶段的业务性能指标 |
在一次性能测试活动中网络传输的数据量的总和。吞吐量一般是不具备参考价值的,应当用吞吐率。
吞吐率:单位时间内传输的数据量,可以用 页面/s、请求/s、Bytes/s等来统计。一般针对不同场景下的性能测试要求来使用不同的统计方式。
耐力测试:有时也叫浸泡测试,是一种非功能性测试。耐力测试是长时间测试具有预期负载量的系统
,以验证系统的行为是否正常。
尖峰测试:尖峰测试用于确定系统在负载(比如用户请求数)突然变化时的系统行为。这种测试是通过突然增加或减少由用户产生的负载来观察系统的行为。测试的目标是确定性能在这样的场景下是否会受损,系统是否会失败,或者是否能够处理负载的显著变化。尖峰测试的核心是负载变化的突然性,所以也算是一种压力测试。