文章目录
- 一、前言
- 二、自定义脚本
- 三、自定义请求编写(Java Sampler)
- 四、自定义函数
- 五、小结
一、前言
掌握 JMeter 的脚本编写和执行,这基本已满足大部分的性能测试需求,但是面对各种各样的项目技术方案,有些需求是需要我们写代码实现的,那么性能测试工程师对 JMeter 二开就无法避免了,而 JMeter 作为 Apache 的开源性能测试工具允许使用者对其进行二次开发扩展,本文对常见的几种二开方法进行总结,方便大家学习查阅。
二、自定义脚本
JSR223 是一个用于将脚本嵌入 JMeter的Java源代码的框架。相当于一个小巧的 Java 源码解释器,简单来说就是可以在里面写代码,然后通过解释语言翻译成插件可以识别的指令去执行相关操作。
由于 JSR223 组件可用于增强对测试计划的控制,因此它们是使用 JMeter 进行性能测试的最有用工具之一。有一整套JMeter JSR223 组件:一个采样器,一个断言,前后之处理器,一个监听器和一个定时器。
在 JSR223 组件中使用一系列解释语言,常见的有 Groovy 和 BeanShell。
这里以 BeanShell 举例,其常被用于对请求或者返回内容进行获取或者加工,其中 prev 是对当前的取样进行访问,执行了对响应状态码、响应信息、请求头等的操作,
常见用法举例:
#获取响应的状态码
log.info("code is "+prev.getResponseCode());
#获取响应信息
log.info("response is "+prev.getResponseDataAsString());
#获取头文件中ContentType类型
log.info("content_type "+prev.getContentType());
#获取取样器请求首部字段
log.info("header "+prev.getRequestHeaders());
通过以上方式,基本实现了对请求的基本信息的获取,然后我们可以对这些信息做进一步的提取、判断等操作。
另外,我们可以使用 log 变量访问组件的 Logger 对象。Logger 类对于脚本编写非常重要,因为可以让我们更轻松地调试脚本,通过信息输出到 JMeter 日志,方便我们调试脚本。
BeanShell 日志打印示例如下:
#打印线程号
log.debug('Current thread number:'+ String.valueOf(ctx.getThreadNum()));
#打印启动采样器名称
log.info('Sampler '+ sampler.getName()+' started’);
#自定义告警
log.warn('Could not convert string, using default encoding');
#打印错误信息
log.error("Malformed URL detected:", e);
#打印响应数据
log.error("Response data:"+ prev.getResponseDataAsString());
其它使用方式可以参考本文:性能工具之 JMeter 快速入门
注意在 JMeter 高并发时不建议使用 BeanShell ,因为其消耗资源较多,相比 Groovy 要更高效。
三、自定义请求编写(Java Sampler)
实现 Java Sampler 自定义请求的两种方式
- 继承 AbstractJavaSamplerClient 抽象类;
- 实现 JavaSamplerClient 接口。
通过阅读源码可以发现 AbstractJavaSamplerClient 抽象类是 JavaSamplerClient 接口的子类,所以,我们可以新建一个 JavaClass,并继承 AbstractJavaSamplerClient。
AbstractJavaSamplerClient中 默认实现了四个可以覆盖的方法,分别是 getDefaultParameters(), setupTest(), runTest()和 teardownTest()方法。
- getDefaultParameters 方法:主要用于设置传入界面的参数,这个方法由 JMeter 在进行添加 JavaRequest 时第一个运行,它决定了你要在 GUI 中默认显示哪些属性。当每次在 GUI 里点击建立 java requst sampler 的时候会调用该方法。该方法设置了 parameters 的初始值,也可以在 sampler 的 GUI 界面做进一步的修改;
- setupTest方法:初始化方法,用于初始化性能测试时的每个线程,用于初始化测试脚本里面用到的变量,这些变量会在后续执行中使用。
- runTest方法:性能测试时的线程运行体,实现功能逻辑的主方法,每个线程会循环执行这个方法。
- teardownTest:方法为测试结束方法,用于结束性能测试中的每个线程,在每个线程执行完所有的测试工作之后执行,有点像 finally 的功能,比如,我开了一个数据库的连接,那么我要在所有的线程完成工作后关闭。
使用案例:
- 性能工具之Jmeter压测Thrift RPC服务
- 性能工具之Jmeter压测Hprose RPC服务
四、自定义函数
要实现二次扩展函数,主要有两点:
1、定义function 的类的 package 声明必须包含 .functions
(新建的包需要特别注意,名字只能是 functions 结尾,否则打包放到 JMeter 中是没有办法识别这个插件)
2、需要继承实现 AbstractFunction 四个方法
- execute方法用于接收Jmeter传入的参数值并执行工作
- setParameters方法用于传递执行过程中的实际参数值
- getReferenceKey方法用于定义函数名字
- getArgumentDesc方法用于描述函数参数
使用案例:
- 性能工具之Jmeter扩展函数及压测ActiveMQ实践
五、小结
通过本文学习,我们知道了如何使用代码方式扩展实现自己需要的工具,使用解释语言脚本和 jar 包插件引入都是工作中常见的,这也是 JMeter 的特色功能,希望大家日常工作中有所说帮助。