记录一次客户端接口(json数据+签名)的Jmeter压测过程

背景:
最近产线出现了接口压力过大,最后引发整个服务雪崩的问题。面对没有测试人员的客观原因,对高频接口的压测在开发过程总显的格外重要。以下记录比较常见的客户端接口的的Jemter 测试过程。

1. 安装Jmeter,参考官网

2. 启动 创建测试计划

步骤:File -> New
这里注意 如果在某个过程中依赖到自己的脚本,需要再这里添加自己脚本的包,保证脚本中的依赖可以加载到,如下图。
在这里插入图片描述

3. 创建线程组

创建步骤参考下图:
在这里插入图片描述
在这里插入图片描述

线程组的的各个参数说明这里引用官网的一段话,来说明:

线程组元素是任何测试计划的开始点。所有控制器和采样器必须在一个线程组下。其他元素,例如 Listeners,可以直接放在测试计划之下,在这种情况下,它们将应用于所有线程组。顾名思义,线程组元素控制 JMeter 用于执行测试的线程数。线程组的控件允许您:
number of threads 设置线程的数量
ramp-up period 设置爬升周期
number of times to execute the test 设置执行测试的次数
每个线程将完全独立于其他测试线程执行测试计划。多个线程用于模拟到服务器应用程序的并发连接。
ramp-up 告诉 JMeter 需要多长时间才能“过渡到”选择的所有线程数。如果使用了10个线程,并且爬升周期为100秒,那么 JMeter 将需要100秒来启动并运行所有10个线程。每个线程将在前一个线程开始后10秒(100/10)开始。如果有30个线程和一个120秒的爬升周期,那么每个连续的线程将延迟4秒。
ramp-up需要足够长的时间以避免测试开始时工作负载过大,并且足够短以至于最后一个线程在第一个线程完成之前开始运行(除非有人希望这样做)。
线程组还允许指定线程生存期。单击 Thread Group 面板底部的复选框来启用/禁用额外的字段,您可以在其中输入测试持续时间和启动延迟您可以配置 Duration (seconds)和 Startup Delay (seconds)来控制每个线程组的持续时间和启动后的秒数。当测试启动时,JMeter 将在启动线程组的线程之前等待启动延迟(秒) ,并在配置的持续时间(秒)内运行。

4. 创建 HttpRequest

步骤见下图:
在这里插入图片描述
在这里插入图片描述
Basic 窗口中的参数,大都比较容易理解, 协议选择,Ip,端口,method, 请求地址等,参数部分 我们稍后说。
Basic 旁边的Advanced 高级设置里面的内容,一般情况下不需要配置,如果你需要设置代理,更换HttpClinet 的实现工具,超时时间设置等,可以进行设置。

请求参数部分
如果是模拟表单方式提交,可以直接在Parameters 处进行请求参数添加,如果后台只接受Json数据请求,则需要在Body中设置 json 参数,见下图
在这里插入图片描述
同时,添加请求头参数 Content-Type: application/json, 见下图打开请求头设置,并添加。如果接口必须要在请求头添加其他参数,可以在此处增加。
在这里插入图片描述

5. 在请求参数中添加签名字段

因为我的测试 是全链路的测试,所以需要完全模拟客户端请求,接口中必须要添加签名参数。由于签名是通过对请求参数的签名算法计算所得。要进行自动化测试,没办法每次都手动计算一次参数,再编辑到 body 中。我们这里通过 自定义 “BeanShell PreProcessor” 前置脚本处理器来完成签名字段的添加。见下图,添加前置处理器。
在这里插入图片描述
在Script 块中添加脚本,我的脚本,如下图:
在这里插入图片描述
脚本如下

import java.util.Map;
import java.util.HashMap;
import com.fasterxml.jackson.databind.*;
import org.apache.jmeter.config.*;
import com.zcbl.utils.SignUtil;

//获取请求的Body参数
Arguments args = sampler.getArguments();
//json格式请求:body只有一个key为空的参数值
Argument args0= args.getArgument(0);
String requestJson = args0.getValue();
log.info("处理前参数:{}",requestJson);
ObjectMapper mapper= new ObjectMapper();
Map params=mapper.readValue(requestJson,Map.class);
// 添加 nonce 值
params.put("nonce",SignUtil.createNonce());
// 签名计算
String sign=SignUtil.sign(params);
// 添加签名参数
params.put("sign",sign);
// 重新设置 请求的json 参数
String jsonData = mapper.writeValueAsString(params);
args0.setValue(jsonData);
log.info("处理后参数:{}",args0);


代码解释

  1. import 中添加了自己的签名工具类SignUtil,其他的包都是jmeter 有的类,可以在lib 下找到。自己的类,像import com.zcbl.utils.SignUtil ,需要在 “创建测试计划” 页,引入jar 包到 classpath。
  2. 逻辑块处理,主要是 获取body 中定义的json 参数,通过jackson 转成map,然后添加额外的 请求字段“nonce” 防重字段,通过签名工具类生成签名,添加签名字段“sign” 到请求参数中,修改body中的参数值为当前修改后的json串。

其实到这里,我们就可以发现,任何刁钻的接口逻辑都可以通过这种方式去调整。这里大家要注意可以利用的上下文变量:
ctx,vars,props,prev,sampler,log 。可以参考官网的javadoc

6. 结果断言

如果判断接口的返回成功失败,可以通过添加结果断言完成。
在这里插入图片描述
下图断言设置,必须包含“success”和“code” 两个的标识匹配才会认为接口返回成功。
在这里插入图片描述

7. 观察测试结果

添加结果树,观察每一个接口的请求情况
在这里插入图片描述

添加图示结果,直观感受各项指标,在整个测试时间中的变化。
在这里插入图片描述
添加总结报告,总结测试各个指标值。
在这里插入图片描述
常见指标名说明:

  • #Samples : 这次测试中共发出了多少请求
  • Average: 平均响应时间(毫秒)
  • Min: 最短响应时间(毫秒)
  • Max: 最长响应时间(毫秒)
  • Error %:本次测试中出现错误的请求数量/请求的总数
  • Throughput:吞吐量,每秒完成的请求数
  • Received KB/Sec:每秒从服务器接收的数据量
  • Sent KB/Sec:每秒请求的数据量
  • No of Samples : 样本数量,总共发送到服务器的请求数

8. 执行测试

设置线程组参数如下图:使用50个线程并发,5秒内完成启动(相当于1秒启动10个),循环次数是无限循环,执行120s,延迟为0。
在这里插入图片描述
点击开始执行,见下图左侧框,观察右侧时间。
在这里插入图片描述
结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

请求参数模拟

对于模拟一个接口,每次请求使用不同的参数。我们可以先批量生成一组csv文件格式的数据。然后通过创建 CSV Data Set Config 映射到jmeter 中。
在这里插入图片描述
在这里插入图片描述
通过设置csv 每行的数据定义,我这里只有一个字段,所有是“token”。如果多个字段,按csv的分隔符定义出来,就可以在jmeter 中通过“${token}” 来使用了。
注意无法在json 数据的body请求数据中直接使用。没办法我通过上面的BeanShell PreProcessor 方式来引用这些变量,并改变请求参数。
如图:
在这里插入图片描述

整个过程参考以下博文:

  1. https://www.cnblogs.com/huahua035/p/11892322.html
  2. https://www.cnblogs.com/qiaoyeye/p/6953099.html
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值