Jmeter是由Java开发,所以有Java基础的完全可以进行二次开发,本篇对Jmeter源码做一个简单的赏析讲解,理解后方便自己做二次开发,没有Java基础的也可以以此作为模板尝试开发。
本次赏析来看函数助手,随机数的生成。函数助手的开发需要去继承AbstractFunction类,并重写其中的方法。
继承:public class Random extends AbstractFunction{}。
函数助手中显示名称:private static final String KEY = "__Random";
函数参数(一个范围内最小值):desc.add(JMeterUtils.getResString("minimum_param"));
函数参数(一个范围内最大值):desc.add(JMeterUtils.getResString("maximum_param"));
函数参数(存储结果的变量名):desc.add(JMeterUtils.getResString("function_name_paropt"));
来看真正实现的代码逻辑,需要获取函数参数,进行逻辑处理并返回:
@Override
public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException {
long min = Long.parseLong(minimum.execute().trim());
long max = Long.parseLong(maximum.execute().trim());
long rand = ThreadLocalRandom.current().nextLong(min, max + 1);
String randString = Long.toString(rand);
if (varName != null) {
JMeterVariables vars = getVariables();
final String varTrim = varName.execute().trim();
if (vars != null && varTrim.length() > 0) {
vars.put(varTrim, randString);
}
}
return randString;
}
获取参数(一个范围内最小值):long min = Long.parseLong(minimum.execute().trim());
获取参数(一个范围内最大值):long max = Long.parseLong(maximum.execute().trim());
生成随机数rand,转换为String类型并返回:
long rand = ThreadLocalRandom.current().nextLong(min, max + 1);
String randString = Long.toString(rand);
生成随机值是一项非常常见的任务。这就是Java提供java.util.Random类的原因。但是,此类在多线程环境中表现不佳。
简单来说,多线程环境中Random性能不佳的原因是竞争 - 假设多个线程共享同一个Random实例。为了解决这个限制,Java 在JDK 7中引入了java.util.concurrent.ThreadLocalRandom类 - 用于在多线程环境中生成随机数。
Jmeter压力测试中会涉及到多线程的并发操作,所以使用了ThreadLocalRandom类,我们来看一个生成10-99之间随机数的操作:
int boundedRandomValue = ThreadLocalRandom.current().nextInt(10, 100);
Jmeter源码中使用Long类型是因为要给予足够的长度,max+1的操作是因为包含下限min,不包含上限,所以max+1作为上限,取值可以到max。
最后就是需要存储结果变量名,简单解释就是如果你输入了存储变量名,那么获取你输入的名称,并把返回的最终结果randString通过vars.put()放入所输入的变量名称里:
if (varName != null) {
JMeterVariables vars = getVariables();
final String varTrim = varName.execute().trim();
if (vars != null && varTrim.length() > 0) {
vars.put(varTrim, randString);
}
}
通过阅读Jmeter生成随机数的源码,第一可以了解到多线程下,如何生成随机数。第二就是根据这个模板我们可以自己定制函数助手插件,比如随机生成身份证,手机号。
源码附上,先学习,后实践!
package org.apache.jmeter.functions;
import java.util.Collection;
import java.util.linkedList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import org.apache.jmeter.engine.util.CompoundVariable;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.samplers.Sampler;
import org.apache.jmeter.threads.JMeterVariables;
import org.apache.jmeter.util.JMeterUtils;
public class Random extends AbstractFunction {
private static final List desc = new linkedList<>();
private static final String KEY = "__Random"; //函数助手中显示的名称
static {
desc.add(JMeterUtils.getResString("minimum_param")); //The minimum value allowed for a range of values
desc.add(JMeterUtils.getResString("maximum_param")); //The maximum value allowed for a range of values
desc.add(JMeterUtils.getResString("function_name_paropt")); //Name of variable in which to store the result (optional)
}
private CompoundVariable varName;
private CompoundVariable minimum;
private CompoundVariable maximum;
public Random() {
}
@Override
public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException {
long min = Long.parseLong(minimum.execute().trim());
long max = Long.parseLong(maximum.execute().trim());
long rand = ThreadLocalRandom.current().nextLong(min, max + 1);
String randString = Long.toString(rand);
if (varName != null) {
JMeterVariables vars = getVariables();
final String varTrim = varName.execute().trim();
if (vars != null && varTrim.length() > 0) {
vars.put(varTrim, randString);
}
}
return randString;
}
@Override
public void setParameters(Collection parameters) throws InvalidVariableException {
checkParameterCount(parameters, 2, 3);
Object[] values = parameters.toArray();
minimum = (CompoundVariable) values[0];
maximum = (CompoundVariable) values[1];
if (values.length > 2) {
varName = (CompoundVariable) values[2];
} else {
varName = null;
}
}
@Override
public String getReferenceKey() {
return KEY;
}
@Override
public List getArgumentDesc() {
return desc;
}
}
相互学习,共同进步!



