1 前言
jmeter是apache基金会下的一款应用场景非常广的压力测试工具,具备轻量、高扩展性、分布式等特性。jmeter已支持实现随机数、计数器、时间戳、大小写转换、属性校验等多种函数,方便使用人员使用。如果在使用过程中存在和业务强耦合的常用功能函数,在jmeter不支持的情况下,那就需要单独开发自定义函数实现特定功能。
本文介绍如何开发jmeter自定义函数实现快速生成京东宙斯下单标准sign,同时深刻理解jmeter的插件化机制及高扩展性特性。
2 开发准备
- java基础开发
- maven基本使用
- 开发依赖版本
jdk 1.8.0maven 3.6.3jmeter 5.4.3
3 自定义函数核心实现
3.1 新建项目
- 新建maven项目,这里项目名为:jsf_sampler
- 因为是基于jmeter的扩展,需要依赖包jmeter两个核心包,分别是:
- apachejmeter_core
- apachejmeter_java
- apacehjmeter_functions
pom.xml文件核心配置如下
<groupid>com.jd.jmeter.jsf</groupid>
<artifactid>jsf_sampler</artifactid>
<version>1.0-snapshot</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceencoding>utf-8</project.build.sourceencoding>
<jmeter-version>5.4.3</jmeter-version>
</properties>
<dependencies>
<dependency>
<groupid>org.apache.jmeter</groupid>
<artifactid>apachejmeter_core</artifactid>
<version>${jmeter-version}</version>
</dependency>
<dependency>
<groupid>org.apache.jmeter</groupid>
<artifactid>apachejmeter_java</artifactid>
<version>${jmeter-version}</version>
</dependency>
<dependency>
<groupid>org.apache.jmeter</groupid>
<artifactid>apachejmeter_functions</artifactid>
<version>${jmeter-version}</version>
</dependency>
</dependencies>
3.2 继承实现abstractfunction类
实现类依次实现以下几个步骤
1)新建实现类并继承 abstractfunction
- 注意:实现类的包名必须包含xxx.functions.xxx,jmeter使用命名规则实现实现类的加载。
2)重写以下方法,每个方法的用途见下方代码注释
- execute()
- setparameters()
- getreferencekey()
- getargumentdesc()
/**
* 京东宙斯 下单标准字段常量
*/
private static final string app_key = "app_key";
private static final string app_secret = "app_secret";
private static final string access_token = "access_token";
private static final string timestamp = "timestamp";
private static final string v = "v";
private static final string method = "method";
private static final string buy_param_json = "360buy_param_json";
/**
* jmeter中自定义的函数名,在jmeter的函数助手中可以看到
*/
private static final string func_name = "__gensignfunction";
/**
* 自定义函数的描述,入参,出参,方便使用人员参考使用
*/
private static final list<string> desc = new arraylist<>();
static {
desc.add("this function is used to generate the jd's jos sign value");
}
/**
* 此为自定义函数核心实现类,其中,入参sampleresult为上次运行的结果,sampler为当前的采集器;
* 返回值为该函数的返回值
* @param sampleresult
* @param sampler
* @return
* @throws invalidvariableexception
*/
@override
public string execute(sampleresult sampleresult, sampler sampler) throws invalidvariableexception {
// 入参处理
string param = string.valueof((compoundvariable)paramvalues[0]);
string signresult = paramhandler(param);
return signresult;
}
/**
* 按京东宙斯sign加密规则生成标准sign
* @param param
* @return
*/
public string paramhandler(string param){
map<string,string> valuemap = new hashmap();
// 按&符号分割
string[] paramarray = param.split("&");
for (int i = 0; i < paramarray.length-1; i++) {
string key = paramarray[i].split("=")[0];
string value = paramarray[i].split("=")[1];
valuemap.put(key,value);
};
// 京东宙斯标准sign
string josgign = encryptutil.getsignature(valuemap.get("app_secret")+buy_param_json+valuemap.get("360buy_param_json")
+access_token+valuemap.get("access_token")
+app_key+valuemap.get("app_key")
+method+valuemap.get("method")
+timestamp+valuemap.get("timestamp")
+v+valuemap.get("v")
+valuemap.get("app_secret"));
return josgign;
}
/**
* 配置入参,jmeter函数助手入参
*/
@override
public void setparameters(collection<compoundvariable> collection) throws invalidvariableexception {
paramvalues = collection.toarray();
}
/**
* 此方法返回自定义的函数名称
*/
@override
public string getreferencekey() {
return func_name;
}
/**
* 此方法返回函数描述信息
*/
@override
public list<string> getargumentdesc() {
return desc;
}
3.3 最终项目结构
4 jmeter加载扩展包
以上开发完成,打包此项目,注意这里的打包要包含依赖包。
4.1 maven构建配置
<build>
<finalname>${project.artifactid}</finalname>
<defaultgoal>install</defaultgoal>
<plugins>
<plugin>
<groupid>org.apache.maven.plugins</groupid>
<artifactid>maven-compiler-plugin</artifactid>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupid>org.apache.maven.plugins</groupid>
<artifactid>maven-assembly-plugin</artifactid>
<configuration>
<descriptorrefs>
<descriptorref>jar-with-dependencies</descriptorref>
</descriptorrefs>
</configuration>
<executions>
<execution>
<id>assemble-all</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
4.2 项目打包
打包指令如下
mvn package -dmaven.test.skip=true
4.3 jmeter加载扩展包
将打包后的扩展包放置到jmeter的ext目录:apache-jmeter-5.4.3/lib/ext/
启动jmeter后,jmeter会自动加载ext目录中的扩展包
打开jmeter函数助手后,可以看到本次实现类中打印的相关日志
5 自定义函数调用调试
5.1 打开jmeter函数助手,选择自定义函数
5.2 京东宙斯接口验证
这里使用京东快递获取预制运单号接口,输入get请求后,直接点击运行函数【generate & copy to clipboard】,出参返回32位sign值。
get请求入参
method=jingdong.etms.waybillcode.get&app_key=349559fae87e66826499890862e40a44&access_token=c8c2bdc8d1684630bb771a503d5b5a7fkyzh×tamp=2022-01-28 15:10:00&360buy_param_json={"prenum":"1","customercode":"10k43816","ordertype":"0"}&v=2.0&sign=ebb52c6ceda34703ade72d4aa4d8f316&app_secret=29959e4cadc14ff4998d4fc26d1e5063
6 总结
本文通过自定义函数实现了京东宙斯下单标准sign的生成,希望通过本项目大家可以学习到:
- 如何二次开发jmeter,实现自己特有的自定义函数。
- 理解为何官方介绍jmeter是插件化的,高扩展性特性。
- 更好的理解jmeter内部处理机制。
发表评论