有效的性能测试能给研发运维团队提供有效的容量规划能力,系统风险识别,性能瓶颈识别,性能调优指导,保障尽量避免如上问题的发生(新系统上线,重构,性能调优)
性能需求指标:
性能模型:
性能方案:
性能监控:这块会结合prometheus具体的讲
性能场景执行:比如时长,压测范围,目标值
性能结果/报告:略
一、步骤:
需求分析与测试设计(性能需求目标+业务模型拆解)
环境设计与搭建(尽可能接近线上真实场景)
测试数据准备(基于模型的数据准备)
性能指标预期(性能需求目标)
发压工具配置及脚本编写(压力策略)
测试过程(预计的前置准备过程,和压测时间点规划)
结果分析与测试报告
需求分析和测试设计:面试会问时间指标,容量指标,资源利用率指标这三者的关系,怎么样去定义或设置这些指标,什么样的性能测试是有效的,到了什么点可以停下来
下面是经典的性能测试的性能拐点图
从图来看,压测大致分成3个阶段
第一阶段:随着并发用户数递增,吞吐量/响应时间在可靠范围内,cpu资源伴随并发用户数进行递增,这些值处于合适范围内,我们可以在这个阶段获取容量规划的最优指标。
第二阶段:当资源利用率达到一定的限制,比如CPU/mysql达到95%以上,响应耗时的利用率大,会拖累响应耗时,这个阶段是系统风险的极限值。当然实际场景中这个阶段非常的短,很快就进入第三阶段。
第三阶段:压到峰值后,系统无法承受,出现mq积压/监控开始告警等情况,响应速度很慢,用户已经有感知
1、需求分析与测试设计
步骤:
性能项目按目标场景分类:
本次实战中,我们可以定义为新系统上线的容量测试,目标为获取系统最大容量
测试场景:基准场景(单交易容量场景)
容量场景(递增场景、最大TPS,最快响应时间场景)
基准测试一般基于配置测试,通过配置测试得到数据,并将这个这个数据作为基准来比较每次调优后性能是否有所改善。
容量测试的目的是通过测试预先分析出反映软件系统应用特征的某项指标的极限值(如最大并发用户数、数据库记录数等),系统在其极限值状态下没有出现任何软件故障或还能保持主要功能正常运行
性能指标的估算:
2、测试数据准备与构造:
3、性能指标预期
不同性能测试方式下指标预期会有差异
4、工具选型/发压工具准备
1. Jmeter工具介绍
① 集成包,解压即可使用,windows、linux通用(依赖java环境)
② jmx脚本为xml文件,win、linux环境均可直接运行
③ 多线程并发
④ 运行完脚本会生成jtl日志,可在win环境界面工具中查看,统计
2. 脚本的编写
① http请求
② 其他
3. 命令:
- 启动压测: ./jmeter -n -t hb.jmx -l hb.jtl
4. 压测场景:
单接口/复杂事务->jmeter场景构造
5. 压力需求:
<1000 QPS or 万级以上 -> jmeter分布式支持
6. 是否周期性:
Jmeter jmx场景文件,数据驱动,结果落库
7. 二次开发需求:
Jmeter开源插件化思想,支持thrift,dubbo等多种协议,开源快速平台化
8. 问题支持:
Jmeter开放社区,广泛使用
5、压测过程说明/共识
6、结果分析和测试报告
二、 被测系统介绍:
三、压测目标预估
常见方式:线上取生产数据并统计
实际中也可以直接去nginx配置:
巧用shell技巧:cat var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -k 1 -nr
可以用这个拉出最常访问的接口
cat var/log/nginx/access.log | grep GET | awk '{print $7}' | > uri.txt
,然后再用csv的方式放在jmeter里面进行读取来做流量的请求,这样也比较快,不需要自己构造参数和url,相当于回放流量。post请求不适用四、电商系统之简单场景:
五、电商实战用户注册模块
${phone_no}
添加前置处理器
执行
这样的好处是涉及到ip,host之类的只需要修改配置文件,后续想把jmeter文件做成平台化的话,可以很好的进行数据驱动
接着我们进行登录
String temp=var.get("temp");
DigitalUtils.md5Hex(temp);
六、报告的展示
略,详见之前文章 戳这里
七、电商实战之日常场景
我们可以先跟pm确认具体的场景,然后再通过抓包或跟研发确认的方式确认下要压测的接口。
浏览首页4个接口的预估占比分别是2:4:2:1
登录在电商场景其实不太重要,通常需要的是登录后保存下来它的cookie或者token啥的,之前我们已经通过脚本把它存在某个目录下
浏览首页涉及2个点:登录鉴权,流量控制。
首先,我们来获取token,新建一个线程组,再新建两个事务控制器
因为这次登陆验证是放在header里,所以我们新建一个header manager来获取鉴权信息
然后我们通过csv的方式读取之前存下来的token
新建homeContent(访问首页)接口,然后放到HomePageView下面
首页下面可能会有很多分类,1次首页访问我们可能会访问2次商品分类,我们怎么控制访问首页和访问商品列表是1:2的关系呢?这个时候我们可以使用Loop Controller(逻辑控制器-循环控制器)
然后我们在这个控制器下新建获取首页商品分类请求
这里需要传获取parentid,不建议写死,这里采用从数据库获取数据,然后放在文本上,然后直接放到csv里进行读取的方式(或也可以从nginx里面获取)
建议所有请求后面都加一个校验
接着,我们新建分页获取推荐商品的
接着,我们再新建点击分类专题页的请求,因为这个我们模拟的是人数比其他三个请求少一半,我们采用逻辑控制器的方式来做
接着我们再新建请求(其中cate_id我们就跟上面一样,直接从数据库读取,然后放在csv进行读取)
接着,我们正式开始压测
我们重点关注错误率和响应时间,确认要停止还是继续压测
下面,来看添加购物车操作
我们先新建一个事务服务器
再在底下新建一个请求
然后修改下
准备测试数据
以csv的格式导入
我们可以通过看log定位问题
下面我们来刷新购物车
添加校验
添加订单
获取会员的订单列表
根据购物车信息生成订单信息
造数据生成收货地址
创建确认单
取出里面的id
根据购物车信息生成订单
提取orderid
支付成功的回调
添加校验
至此整个流程串起来了,可以开始压测查看效果
我们加压的时候一般采用递增式加压,所以这边可以用utimate thread group的方式进行加压
我们先新建这个,然后把之前的接口全部放到它的目录下
设置参数
后面跳转了下5个参数,这个为准
字段 | 含义 |
---|---|
start thread count | 初始线程数 |
initial delay. sec | 延迟时间 |
startup time.sec | 开始时间 |
hold load for.sec | 持续时间 |
shut down time | 结束时间 |
后台执行程序(执行前记得关闭查看结果树之类的选项,避免影响结果)
执行前记得把recycle改成true
刚刚配置的参数也改下
然后我们可以开始跑
看看压测情况
因为压测时候我们关心是最近的数据
17:03之前5个并发用户已经可以承载最大量级
响应耗时会非常高,而且错误率已经很大了,我们确认下这个错误率是否在承受范围内,不是的话要快速停下来
已经达到2s
整个性能曲线已经很差
在4-5个并发的时候系统就已经达到了系统极限,在往上并发用户增加时响应耗时没有增加,错误率开始大大增加,达到了性能拐点,我们在17.03:30s的时候,user是3的时候,系统还比较稳定,后面错误率在03:20s的时候大大增加,系统超过限制,错误的接口主要在orderpay,order,generateOrder接口,主要集中在订单服务上。首页之类的主要是数据库读的操作,对性能要求不大。cartItem不需要校验是否成功插入,更多是覆盖的操作,对数据库压力较小。压力主要集中下单操作,一是订单流程长,二是涉及多个协调动作。从耗时结果看,耗时主要发生在generateOrder,达到2s以上,HomePageView和HomeContent也会随之增加,这两个和订单用了同一个数据库,数据库一致情况下,整个数据库的响应都会变慢。
下面是jmeter其他功能的一些介绍
1、如何达到一定错误率后停止压测?
jmeter有个插件
2、性能测试环境搭建?
答:最好配置跟线上类似或者等比缩放
3、错误率最好是多少?
答:不超过1%