性能测试是什么?
- 性能测试:指通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试。
性能要求
- 用户
- 响应速度
- 稳定性
- 开发
- 架构是否合理
- 数据库设计
- 代码
- 系统管理员
- 资源利用率(合适的比例)
- 可扩展性
- 系统容量(可容纳的用户请求)
- 稳定性
性能测试应用场景
- 能力验证 关注在给定的软硬件条件下,系统能否具有预期的能力表现
- 规划能力 关注如何使系统具有我们要求的性能能力
- 性能调优 主要用于对系统性能进行调优
- 缺陷发现 发现缺陷或问题重现、定位手段
- 性能基准比较 比较每次迭代中的性能表现变化,判断迭代是否达到了目标
性能测试类型
- 基准测试:在给系统施加较低压力时,查看系统的运行状况并记录相关数做为基础参考。
- 并发测试:测试多个用户同时访问同一个应用、同一个模块或者数据记录时是否存在死锁或者其他性能问题。
- 负载测试:是指对系统不断地增加压力或增加一定压力下的持续时间,直到系统的某项或多项性能指标达到安全临界值,例如某种资源已经达到饱和状态等。
- 压力测试:压力测试是评估系统处于或超过预期负载时系统的运行情况,关注点在于系统在峰值负载或超出最大载荷情况下的处理能力。
- 稳定性测试:在给系统加载一定业务压力的情况下,使系统运行一段时间,以此检测系统是否稳定。
性能测试基本概念
-
并发数
- 并发用户数:某一物理时刻同时向系统提交请求的用户数,提交的请求可能是同一个场景或功能,也可以是不同场景或功能。
- 在线用户数:某段时间内访问系统的用户数,这些用户并不一定同时向系统提交请求
- 系统用户数:系统注册的总用户数据
- 吞吐量(TPS) : 单位时间内系统处理的客户端请求的数量(完成一个业务事务的过程)
- 响应时间 :从用户发送一个请求到用户接收到服务器返回的响应数据这段时间就是响应时间
-
资源利用率 :指的是对不同系统资源的使用程度,通常以占用最大值的百分比来衡量
- CPU:就像人的大脑,主要负责相关事情的判断以及实际处理的机制
- 内存:大脑中的记忆块区,将眼睛,皮肤等收集到的信息记录起来的地方,以供cpu进行判断,但是是临时的,访问速度快,如果关机或断电这里的数据会消失。
- 磁盘IO:大脑中的记忆区块,将重要的数据保存起来(永久保存,关机或断电不会丢失,速度慢),以便将来再次使用这些数据。
- 网络:
模拟用户的真实、峰值和异常的请求量(单位时间的请求数量*单位请求内容大小)去访问系统,监控其性能情况(TPS、响应时间和资源利用率)并获取。
需要准备什么?
环境选择:与线上保持一致
系统环境
- 线上或者uat环境
- 数据请求打标签,区分测试数据与真实数据
- 增加测试挡板
- 优点:不需要搭建环境和监控
- 缺点:只能选择流量空闲期,不能进行过高的压测,测试时候要及时跟开发沟通(线上异常警告)
- 搭建环境
- 组网模型: 需要评估测试组网与生产组网差异,至少满足最低配置要求
- 组网类型:单机/双机/单机集群/双机集群/各种组合类型
- 硬件: cpu/内存/磁盘读写/网卡
- 软件:操作系统类型/服务/数据库/文件库/第三方组件
- 消息交互:同步/异步
- 数据模型
- 系统初始数据:
- 分析系统上线后数据量/历史数据
- 计算出系统每个阶段数据容量,数据类型,数据比例
- 根据不同阶段分别进行数据预制
- 测试新增数据:
- 业务场景确定后根据具体业务场景定义输入和输出数据
- 结合具体的呼叫模型进行数据预制
- 系统初始数据:
- 组网模型: 需要评估测试组网与生产组网差异,至少满足最低配置要求
执行机环境
- 网络与用户保持一致
- 组网:单机(4U8G)一般只能支持2000tps左右),场景超过需要更高的配置
-
调优
- 网络设置
- 测试软件
- 系统对软件的限制
测试工具 :与开发技术栈一致
- ApacheBench: Apache 服务器自带的一个web压力测试工具,简称ab
- Wrk:一款针对 Http 协议的基准测试开源工具,支持lua脚本
- Apache JMeter(常用): Java 编写的应用程序,支持插件和jar包.
- Locust:一个开源负载测试工具。使用 Python 代码定义用户行为,也可以仿真百万个用户。
- LoadRunner(付费专业):HP公司提供的一款性能测试工具,通过模拟成千上万个用户实施并发操作,测试系统的性能,并且提供详细的测试结果分析,协助用户查找问题。
- Spirent(付费专业):自带硬件的大流量网络测试仪
监控软件
场景建模
出发点
- 界面反应慢
- 界面卡顿甚至无响应
- 请求超时
- 使用过程中程序闪退
- 高峰时期程序报错
需要考虑的问题
- 模拟与真实场景、真实组网和真实数据之间的差异性
- 测试过程中的执行模型问题(缓存)
- 测试执行过程中的资源监控问题
- 行业或者同行标准
否则结果与现实存在很大差距,测试结果不准确
场景选取
- 分析用户使用场景,掌握用户需求(秒杀或者持续请求)
- 提炼用户关注度较强的功能
- 分析用户操作频繁的功能
- 分析系统中可能的大数据量操作【文件读写,图片浏览,事务队列,事务机制】
- 分析系统关键功能【后台服务,缓存,调用的功能组件】
- 分析用户组合航警,操作比例以及操作时延
执行模型
- 压力测试
- 负载测试
- 性能测试
测试过程中有哪些内容?
系统瓶颈分析
整体思路:从前到后,从表象到内部
- 首先排除压力机自身的问题,如CPU、内存,网络,脚本编写等
- 监控中间件的访问日志,观察响应时间,大体确定耗时处于哪一段
- 排查网络问题,监控压力机到后端服务器的网络,以及各服务器间的网络,是否达到网络上限
- 监控服务端所有机器的操作系统负载,如CPU、内存、磁盘、网络是否达到瓶颈
- 监控应用服务器的日志,查看是否存在ERROR日志,比如TimeOut或其他类型报错
- 监控各中间件的连接数,如nginx、tomcat、mysql等,是否达到上限
- 监控应用程序线程状态,使用jstack或jvisualvm查看是否有死锁、阻塞等情况
- 监控应用程序的jvm,使用jstat或者jmap查看GC情况,是否内存泄漏等
- 使用jprofiler监控应用程序,可以查看耗时比较长的代码方法
- 监控数据库,是否存在慢查询,一般数据库CPU高都是因为SQL语句效率低造成的
- 在sql语句前加上explain,可以分析这条sql语句的执行情况 explain select * from teacher
- Type列可能的值
Const:表中只有一个匹配行,用到primary key或unique key
Eq_ref:唯一性索引扫描,key的所有部分被连接联接查询使用,且key是unique或primary key
ref:非唯一性索引扫描,或只使用了联合索引的最左前缀
Range:索引范围扫描,在索引列上进行给定范围内的检索,如between,in(1,100)
Index:遍历索引...
All:全表扫描
Prossible key:使用哪个索引能找到行
Keys:sql语句使用的索引
rows:mysql 根据索引选择情况,估算查找数据所需读取的行数
- Type列可能的值
- 联合索引
- 连接数
- 数据库架构优化
- 读写分离,主从配置
- 硬件调优
- 在sql语句前加上explain,可以分析这条sql语句的执行情况 explain select * from teacher
- 检查数据库执行计划,是否有全表扫描,以及索引不生效的情况
- 检查系统外部依赖情况,如果外部依赖系统性能差,也会造成本系统性能低
- 对于不好定位的问题,可以考虑采用模块隔离法来确定问题
优化方案
- sql
- 在 where 及 order by 涉及的列上建立索引,避免全表扫描,索引不要太多,一个表一般不要
超过4个索引 - 避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描
- 查询语句中不要使用 *,减少内存使用
- 尽量减少子查询,使用关联查询(left join,right join,inner join)替代
- 减少使用IN或者NOT IN ,使用exists,not exists或者关联查询语句替代
- or 的查询尽量用 union或者union all 代替(在确认没有重复数据或者不用剔除重复数据时,
union all会更好) - 合理的增加冗余的字段(减少表的联接查询)
- 建表的时候能使用数字类型的字段就使用数字类型(type,status...),数字类型的字段作为条件查询比字符串的快
- 在 where 及 order by 涉及的列上建立索引,避免全表扫描,索引不要太多,一个表一般不要
- 代码
- 使用对象池减少对重复对象的创建;
- 调整对后端的连接
- 增加本地缓存
- 如果不涉及事务的情况下,考虑使用Nosql进行存储
- 一次请求合并多次操作
- 由串行修改为并行操作
- 同步修改为异步
测试注意点
- 记录性能指标(数值和图片)
- 监控请求是否正常,分析失败原因
- 测试总体曲线是否呈现波峰或者随着请求量增大趋于水平
测试报告
- 测试场景
- 结果与分析
- 结论
- 风险点
网友评论