web接口性能测试
目录
一,关于性能测试
1.1 概念
性能测试概念 | 目的:为了发现系统性能问题或获取系统性能相关指标而进行的测试
一般在真实环境 或 特定负载环境下,通过一些工具模拟实际软件系统及其操作,同时监控性能各项指标,最后对测试结果进行分析来确定系统的性能情况
性能好不好?—— 通过指标评估
1.2 常见指标
①并发数
- 从业务层面看:并发数指的是在同一时刻使用系统的用户数
- 从服务端层面看:并发数指web服务器在同一段时间内为了处理浏览器请求而“建立的http链接数”或“生成的处理线程数”
场景:
- 一个已经处于生产环境的web系统,有5000名员工的账号信息,最多只能让2500人同时使用,那么这个系统的业务并发用户是2500;
- 假设系统有浏览页面、填写订单、提交订单、查询订单四种操作,那么实际并发用户数是“提交订单”和“查询订单”这两个和系统有数据往来的操作的用户
②吞吐量
- 单位时间(1 s)内处理的并发数,直接体检软件系统的负载承受能力
- 吞吐量越高,代表系统能承受的并发更多,性能越好
场景:有AB两种
- A:有100个并发用户,每个用户每1秒发出一个请求
- B:有1000个并发用户,每个用户每10秒发一个请求
- A和B场景的吞吐量相同,都是每秒100个请求,但是A场景思考时间短,因为A场景需要系统每秒处理,而B场景预留了10秒的处理时间,所以A场景占用的系统资源更多
- 打个比方,A场景就需要100个线程,每个线程每秒处理100个请求,而B场景只需要10个线程,每个线程每秒处理1个,加上10秒的处理时间,所以A场景需要更多的系统资源
③响应时间
- 表示应用系统从请求发出开始,到客户端收到最后一个字节数据所消耗的时间
- 对于web系统而言,系统响应时间包含 前端展现时间(页面渲染时间)和 系统响应时间(包含服务器程序、数据库和网络通信等响应时间)
关于拐点:
- 空闲:并发用户少,系统吞吐量低,系统响应时间短
- 增长:并发用户增加,系统吞吐量开始线性增长
- 饱和(拐点):当吞吐量到达了某个点后,用户请求不再被立即处理,响应时间随之变长,系统性能开始下降
系统性能的拐点通常是性能吞吐量测试的主要目的
④TPS 和 QPS(transaction per second,)
- TPS:每秒处理的事务数,用于衡量系统在一定时间内能够处理的事务数
- 事务:事务代表一个完整的功能,比如一个接口、多个接口、一个流程等
- QPS:每秒查询率,若一个事务中只有一个接口且是查询接口,则QPS = TPS
场景:
- 假设一个系统1分钟处理1000个业务,那么TPS = 1000 / 60 = 16.7
- 某一年最高的一天有10万笔交易,预测明年TPS需要多少合格?这里我们假定每笔交易是一个事务,理想 TPS 应该是 100000 / 24 * 60 * 60 = 1.2,然而实际上订单并不真是平均每秒一个,应该是在某段时间突然增长,所以:
- ① 如果没有更详细的数据,则根据二八定律:TPS = 100000 * 0.8 / 24 * 60 * 60 * 0.2 = 4.6(80%的事务在20%的时间内完成)
- ② 如果有详细的数据,比如有5万比交易在晚上8~9点完成:TPS = 50000 / 60 * 60 = 13.9
⑤资源利用率
- 通过查看系统占用情况分析资源瓶颈
- 服务器:CPU、内存、磁盘、网络等
1.3 性能测试关注点
不同角色看待性能测试的侧重点不同,因为从客户端发起一个请求到服务器收到并处理请求的整个过程中,各阶段都可能存在性能问题
①终端用户
- 对于用户来说,直接表现为用户进行业务操作的主管响应时间
- 用户重点关注从提交请求到收到响应的时间,包括系统响应时间和前端展现时间,这也是性能测试的最终目标
②系统运维人员
运维人员处理关注单个请求的响应时间,更关注大量用户并发访问时对系统的影响,以及更大负载情况下系统健康状态,从而执行系统的整体的策略:
- 策略①:关注全局利益最大化,对最大并发用户和系统响应时间进行权衡取舍
- 策略②:系统并发处理时间、系统容量、数据库调优、以及长时间运行稳定性和可扩展性
- 例如:A方案,当100万并发访问用户,登录响应时间3秒;B方案,500万并发访问用户,登录响应时间8秒
- 这种情况下运维人员更倾向于第二种
③开发人员
- 关注算法设计、架构设计、性能最佳实践、数据库相关、软件性能的可测试性等方面
- 例如:对于算法,要保证高效,无内存泄漏;对于架构,要保证系统容量和性能可扩展
④性能测试人员
- 工作重点在于性能测试场景的设计、脚本的开发和执行,以及性能缺陷的排查和定位
- 测试人员除了具有及其宽广的知识面,如系统架构,存储架构,网络架构等全局的知识,还要有大量知识积累,比如数据库SQL语句的执行计划调优、JVM垃圾回收、多线程常见问题等
1.4 分类
基准测试
- 又称单用户测试,主要用于检测系统在较低压力下的运行状况并记录数据
- 当性能测试环境确定以后,通常选取业务模型中的重要业务作为基准来进行测试,检验业务完整性和正确性
- 对被测系统施加一定压力,从而获取被测系统在单用户运行情况下的各项性能指标,为多用户并发测试和混合场景测试等提供参考依据
并发测试
- 用于评估被测系统的某些特定操作同时发生时的性能表现
- 例如,被测系统被多个用户同时登录时的响应能力,或系统的某一功能被多个用户同时操作时的性能表现
- 通过并发测试,不仅可以获得被测系统在多用户并发操作时的性能指标,还可以发现被测系统在并发条件下可能发生的问题,如内存泄漏、线程锁、资源争用问题。例如,通过模拟多个用户同时访问某一条件数据,或模拟多个用户同时更新数据,可能会发现被测系统的数据库访 问错误、写入错误等
- 几乎所有的性能测试都会涉及一些并发测试
- 但并发测试对并发时间要求比较苛刻,通常需借助专门的性能测试工具,采用多线程或多进程的方式来模拟多个虚拟用户的并发性操作
负载测试
- 是性能测试的一种测试类型,用于评估被测系统在预期的不同负载下的行为,负载测试关注系统处理不同负载的能力,这些负载可通过控制并发用户或者进程的数量来实现
- 进行负载测试时,通过对系统不断增加并发访问负载,监测系统性能的变化,直到系统的某项或多项性能指标达到安全临界值,最终确定在满足该安全临界值的性能指标下,系统所能承 受的最大负载量
- 简而言之,负载测试是通过逐步加载的方式来确定系统的处理能力。类似于举重运动,通过不断给运动员增加重量,确定运动员在其身体状况保持正常的情况下所能举起的最大重量
- 通过负载测试可以获取系统能够达到的峰值指标
- 例如,一个软件系统的响应时间要求不超过2秒,如果在这个前提下不断增加用户访问量,系统的响应时间就会变长。假设当访问量超过1万人时系统的响应时间超过2秒,那么就可以确定在系统响应时间不超过2秒的前提下,系统的最大负载量是1万人。负载测试可用于系统的性能验证、 性能诊断和性能调优等场景
压力测试
- 用于评估被测系统在⾼于预期、⾼于指定容量负载需求或低于最少需求 资源的条件下的⾏为
- 压力测试关注被测系统处理超出预期或特定峰值负载的能力,也可以用于评估系统在资源匮乏时的处理能力,比如在可用的计算能力、带宽和内存资源不足的条件下系统的表现
- 进行压力测试时通常采用逐步增加系统负载的方式,使系统某些资源达到饱和甚至失效,从而发现那些只有在高负载条件下才会出现的缺陷,如同步问题、内存泄漏等
- 通过对被测系统进行压力测试,也能找出被测系统的性能拐点,获得系统所能提供的最大服务级别(系统所能承受的最大压力),评估系统在峰值负载或超出最大负载情况下的处理能力
- 压力测试主要用于性能诊断、性能调优和容量规划等场景
稳定性测试
在负载测试的基础上,执行较长时间的测试以检查系统的稳定性。通常较长时间指 3 * 24 小时以 上。
二,Jmete基础
2.1 下载安装
Apache JMeter 是 Apache 组织基于 java 开发的压力测试工具,用于对软件做性能测试,可以从下面的地址下载 tar 包,可以用 WinRAR 解压:
Apache JMeter - Download Apache JMeter
https://jmeter.apache.org/download_jmeter.cgi
有两种方式打开 JMete 操作页面
①通过bat文件
直接双击 /bin 目录下bat文件即可:

②命令行启动(推荐)
将bin目录添加到系统环境变量里,之后就可以通过命令行输入“jmete”直接启动:

此外,jmete 也是支持中文的,修改配置文件的这个内容即可在下次启动后将语言切换成中文:

2.2 基本使用
①添加线程组
因为后面要对业务有一个并发执行的环境

②在线程组下添加 http 取样器

③填写http请求相关数据

④在线程组下添加“查看结果树”监听器

注意:如果是在http请求右键,那么该结果树只会显示这一个请求的执行结果,如果有多个http请求的话也只能显示一个,所以要想同时显示多个http请求的结果,需要右键“线程组”添加结果树才行
⑤运行并查看结果

2.3 并发请求
首先是清除我们上一次的结果:

然后回到“线程组”,修改线程数即可:

点击运行后就会发出10此请求:

三,基础组件
3.1 线程组

- ①:假设我们有5个HTTP请求同时测试,如果有接口在运行过程中出现了接口错误,可以采取不同的措施(默认为继续即可)
- ②:线程数叫做“虚拟用户数”
- ③:Ramp-Up 表示性能测试运行时间,假设线程数有10个,http请求只有一个,那么就要求这10个线程在1秒内完成请求的发送;同理,假设http请求有5个,那么就是要求这10个线程在1秒内完成总共50次请求发送
- ④:循环次数就是在上面的基础上增加执行次数,如果为2,那么就是50 * 2 = 100 次请求(如果勾选了永远,则需要配置持续时间,不限次数)
3.2 HTTP 取样器
取样器的使用上面已经介绍过了,下面是一些注意事项:
GET方法要上传数据可以在下面“参数”添加url中数据:

如果请求方法是post,则需要将参数填写进“消息体数据”才能发送:

3.3 查看结果树
目前我们只关注这三个:

当域名或者ip不存在时,也可以查看错误,不同的错误有不同的报错信息,比如:
- 域名或ip无法请求
- 域名或ip存在,但是接口无法匹配(接口不存在)
- 域名或ip存在,接口名称正确,但是参数错误等

3.4 HTTP 请求默认值
当请求同一个接口时,我们的协议、ip、端口号(域名)都是不会发生改变的,每次新增取样器时,都要去配置这些东西,太麻烦了,所以我们可以添加一个配置文件配置下默认值:


配置完成后,如果取样器没有配置对应信息,那么运行时会将“请求默认值”自动添加到取样器的对应参数中,但是如果取样器有部分参数已经配置了,那么将不会添加到对应位置(类似于C++中的缺省参数)
3.6 HTTP信息头管理器
有这样一种情况,有些页面是需要登录的,登录成功后会跳转到首页,但是如果我们使用jmete跳过登录直接访问首页的话,会访问失败,所以我们可以通过http 信息头管理器来应对这种情况

然后我们先登录一个被测网站,然后按F12,找到下列内容复制:

将这个内容也在信息头中拷贝一份,这样就能在jmete中直接获取登录后的页面了:

解释:上面的User_token_header 就是请求头中的一个键值对而已,而这个信息头管理器,作用也就是在请求中加上对应的键值对而已
注意:配置元件的作用域取决于是在那个下面创建的,如果是在大的“测试计划”下创建的,则作用域这一整个文件,如果是在单个http 采样器创建的,则只作用域这一个采样器
3.7 JSON提取器
3.7.1 基本使用
上面的虽然可以解决一时的直接请求登录后页面的情况,但是登录凭证是会过期的,而且我们也不可能每次请求登录后页面都要先登录一次然后再复制粘贴一次,太麻烦
所以我们可以用下这个 JSON 提取器,每次让程序自动提取User_token_header 内容(也可以获取其它报头内容),然后再自动添加进信息头管理器中:



然后添加进信息头管理器中即可:

3.7.2 注意事项
JMeter 有着非常严格的作用域机制,假设我们把json提取器放到线程组目录下,也就是和 http 取样器同目录下

达成下面几个条件时,位于同一目录下的token变量会在每一个符合条件的 http 取样器响应成功后覆盖token的内容:
- 有多个http 取样器
- 都能按顺序请求成功
- 响应数据的json内容中有相同的内容(比如取样器1 和 2 的响应json都有data字段)
当 “ 登录 ” 请求成功时,会将 token 填充为用户登录凭证,然后 “ 列表页 ”,使用登录凭证请求也能成功;但是由于列表页返回的响应json数据中也有data字段,则会覆盖掉原来 token 的用户凭证,结果就是第三个的 “ 用户信息 ”请求失败
解决方法:
其实也很简单,我们的目的就是让json提取器中的token不再被替换,其实只需要把提取器放到“登录”的取样器下面就好了:

3.8 用户自定义变量


这个很好理解,就是我们可以自定义一个类似C语言里的静态变量,然后也按照 $ { 变量名 },的方式去使用即可,也遵循jmeter的作用域划分规则
注意:如果我们用户自定义变量和和前面的变量名相同,那么按照列表顺序,后面的变量值会覆盖前面的变量值
3.9 JSON 断言
有些情况下,虽然能请求成功,但是返回的结果可能不是我们想要的数据,比如登录时,如果我不带用户名和密码,虽然也能请求成功,但是不符合我的预期:
在后面一旦任务多起来,线程躲起来,我们也不可能一个一个去用肉眼观察结果,所以我们可以用 JSON 断言组件来解决:

首先记录下返回的json数据:

然后json断言:

3.10 同步计时器
当我们把线程数改为5后,可以点击右上角的黄色感叹号图标可以查看线程的执行状态:


同步定时器:

注意:
- 如果线程数是5,而我们把同步计时器的线程改为10,那么会卡住,只有当启动的线程数达到10时才会执行,所以同步计时器的线程数数量一定不能超过线程组里配置的线程数(小于是可以的)
- 如果线程数是6,同步计时器线程数改为3,那么也是可以的,它会在前面3个线程执行完毕后继续执行后面三个,所以线程组的线程数可以是同步计时器配置线程数的倍数
3.11 聚合报告
聚合报告是将测试结果进行更直观和详细展示的一个组件

运行后聚合报告界面如下:

说明:
| 指标 | 说明 |
|---|---|
| Label | 取样器名称 |
| 样本(Samples) | 发起的 HTTP 请求调用数 |
| 平均值(Average) | 平均响应时间(单位ms) |
| 中位数(Median) | 请求调用响应时间的中间值,也就是 50% 请求调用的响应时间(ms) |
| 90%百分位(90%Line) | 90% 请求调用的响应时间(ms) |
| 95%百分位(95%Line) | 95% 请求调用的响应时间(ms) |
| 99%百分位(99%Line) | 99% 请求调用的响应时间(ms) |
| 最小值(Min) | 请求调用最小响应时间(ms) |
| 最大值(Max) | 请求调用最大响应时间(ms) |
| 异常%(Error%) | 调用失败的请求占比 |
| 吞吐量(Throughtout) | TPS/QPS,每秒处理的事务数 |
| 接收/发送(KB/sec) | 每秒网络传输的流量大小,单位为 KB,用来衡量网络传输的吞吐量 |
3.12 事务处理器
事务控制器主要用于测试执行嵌套测试元素所花费的总时间。这相当于模拟用户进行一系列操作的测试
例如,在订单提交的过程中,可能需要调用多个接口,并且某些接口可能依赖于前一个接口的结果。在这种情况下,使用事务控制器可以将这些接口统一视为一个事务进行性能测试,从而得到更接近真实场景的性能测试结果

我们把“登录”和“用户信息”的取样器拖到“登录事务”里去:

此时再运行就会看到聚合报告多了一个东西:

此时就相当于把前面的“登录”和“用户信息”看成了一个 取样器,就达到了捆绑测试的效果
3.13 CSV数据文件设置

以登陆接口为例,当我们执行登陆接口的性能测试时,手动配置了用户名和密码为固定的username和 password,然而实际使用中不可能只有⼀个用户登陆,为了模拟更真实的登录环境,我们需要提供更多的用户名 username 和 password 来实现登录操作,简单来说就是让jmeter循环读取一个文件里的内容,然后通过变量来改变用户名和密码
我们先将“用户定义的变量”组件里的固定内容修改为变量:

在当前 .jmx 同级目录下 创建一个 excel 表格并加上多个用户名和密码,最后修改后缀为 CSV:

之后就是设置组件:

运行后就可以看到两次请求传递的参数是两个了(需要将线程数改为2或者将循环次数改为2,并且在设置参数的位置也需要用 ${ } 代替固定值)

四,插件
4.1 安装插件
假设我们需要测试4000个线程并发跑,目前的做法就是直接将线程组里的线程数改为4000,然后运行;但是实际上不是这样的,实际执行性能测试,并发线程数是一点一点加上去的
假设期望并发数是10000,那么第一次是100,第二次是1000,第三次为3000,然后6000,8000,最后10000 这样子,因为如果一上来就是10000,可能会出现一些无法预测的问题和错误
所以我们目前只能通过手动改线程组里的线程数去搞,太麻烦,所以我们需要添加新的线程组,添加新的插件
插件地址为:Install :: JMeter-Plugins.org

然后将插件直接放到jmeter目录的 lib/ext 目录下后,重启jmeter,就可以在页面右上角出现一个图标,表示jmeter可以安装插件了:

先下载监听器插件

然后下载线程组插件

之后我们的线程组和监听器就会多一些东西
4.2 梯度压测线程组


| 框框 | 选项 | 说明 | 总结(以上图数据为例) |
|---|---|---|---|
| 红色 | This group will start | 最大线程数 | 等待0秒后启动0个线程,线程最大数为20 |
| First wait for | 开始运行时等待多少秒开始运行线程 | ||
| Then start | 在上面的基础上设置运行线程的数量 | ||
| 绿色 | Next, add | 每次增加多少个线程 | 设置在3秒内启动5个线程,每一秒增加一次(数量是叠加的,直到达到最大线程数) |
| threads every | 在多少秒内启动上面设置的线程数 | ||
| using ramp-up | 多少秒后再次增加线程数量 | ||
| 蓝色 | Then hold load for | 当达到最大线程数时,保持运行多少秒 | 当达到20个线程时,保持运行25秒,25秒后每隔1秒停止5个线程 |
| Finally, stop | 当上面的时间结束后,设置每隔多少秒开始结束线程 | ||
| theads every | 在上面的基础上,停止多少个线程 |
然后我们把前面线程组里面的东西都拷贝一份过来运行就好了
4.3 出具性能测试报告
需要用到一个命令:
Jmeter -n -t 脚本文件 -l 日志文件 -e -o 目录
-n: 无图形化运行
-t: 被运行的脚本
-l: 将运行信息写入日志文件,后缀为jyl
-e: 生成测试报告
-o: 输出测试报告
这个命令就是将我们项目的 jmx 文件脚本先运行一遍再生成报告的,要注意:输出的目标路径或目录必须为空,不然会报错哦

然后指定目录会出现:

报告就是一个网页,双击 index.html 即可查看测试报告的可视化界面:

更多推荐


所有评论(0)