完成JMeterEngine, ThreadGroup 和 JMeterThread的整合,外围的设施差不多搞定大半了,接下来是把具体的测试逻辑整合进来,既然是框架层面的,需要通用一点,方便客户端自己定义测试逻辑。不过在此之前,还需要研究下Sampler和Listeners,这样对JMeter的整个流程会有全局的把握。先看下图:
SampleListener和TestStateListener作为很重要的两个Listener贯穿了JMeter整个test的生命周期。
先看TestStateListener,两个方法名就能让我们猜到作用:
1) 在测试开始时候调用 testStarted
2) 在测试结束的时候调用testEnded
这些生命周期函数的调用是在什么地方呢?这个又要回到JMeterEngine了,看StandardJMeterEngine#run()方法,在启动ThreadGroup之前以及整个测试结束之后,代码是这样的:
public void run(){
。。。。。。
SearchByClass<TestStateListener> testListeners = new SearchByClass<TestStateListener>(TestStateListener.class); // TL - S&E
test.traverse(testListeners);
// Merge in any additional test listeners
// currently only used by the function parser
testListeners.getSearchResults().addAll(testList);
testList.clear(); // no longer needed
if (!startListenersLater ) { notifyTestListenersOfStart(testListeners); }
test.traverse(new TurnElementsOn());
if (startListenersLater) { notifyTestListenersOfStart(testListeners); }
。。。。。。
////此处省略 n 行代码
。。。。。。
notifyTestListenersOfEnd(testListeners);
}
代码解释如下:
1) 从HashTree中找出所有TestStateListener类型
2) 在测试正式开始之前,触发这些TestStateListener,notifyTestListenersOfStart(testListeners)这个方法中会调用testListener#testStarted方法
3) 在测试执行完之后,再触发这些TestStateListener,notifyTestListenersOfEnd(testListeners)这个方法会调用testListener#testEnded方法
理解了这些,来看看具体三种我们会用到TestStateListener(如上面类图):TestPlan,JavaSampler,RresultCollector,看看他们的testStarted()分别做些什么
1. TestPlan:主要设置一些文件路径,方便查找config, log等文件,不需要再去干预。
2. JavaSampler: 主要是加载client类,类名是根据HashTree中的配置数据。这个比较重要,因为这里是整合测试逻辑的地方,看下代码
@Override
public void testStarted() {
log.debug(whoAmI() + "\ttestStarted");
initClass();
}
private void initClass() {
String name = getClassname().trim();
try {
javaClass = Class.forName(name, false, Thread.currentThread().getContextClassLoader());
Method method = javaClass.getMethod("teardownTest", new Class[]{JavaSamplerContext.class});
isToBeRegistered = !method.getDeclaringClass().equals(AbstractJavaSamplerClient.class);
log.info("Created class: " + name + ". Uses tearDownTest: " + isToBeRegistered);
} catch (Exception e) {
log.error(whoAmI() + "\tException initialising: " + name, e);
}
}
/**
* Gets the Classname attribute of the JavaConfig object
*
* @return the Classname value
*/
public String getClassname() {
return getPropertyAsString(CLASSNAME);
}
3) ResultCollector:主要是初始化File Output,做好写测试结果的准备。代码如下:
@Override
public void testStarted(String host) {
synchronized(LOCK){
instanceCount++;
try {
initializeFileOutput();
if (getVisualizer() != null) {
this.isStats = getVisualizer().isStats();
}
} catch (Exception e) {
log.error("", e);
}
}
inTest = true;
if(summariser != null) {
summariser.testStarted(host);
}
}
so far so good, TestStarted的准备已经完成。按照流程,我们要回到JMeterThread#run()方法了,此方法在上一篇有详述,这里只看相关的代码:
/////In JmeterThread
@Override
public void run() {
......
process_sampler(sam, null, threadContext);
......
}
private SampleResult process_sampler(Sampler current, Sampler parent, JMeterContext threadContext){
......
SampleResult result = sampler.sample(null);
。。。。。。
List<SampleListener> sampleListeners = getSampleListeners(pack, transactionPack, transactionSampler);
notifyListeners(sampleListeners, result);
......
}
private void notifyListeners(List<SampleListener> listeners, SampleResult result) {
SampleEvent event = new SampleEvent(result, threadGroup.getName(), threadVars);
notifier.notifyListeners(event, listeners);
}
如上代码,每一个JMeterThread在运行时,当一个Sampler#sample触发得到一个SampleResult,那么回到JavaSampler,前文所述在TestStarted触发时,JavaSampler作为TestStateListener已经加载了Client类,那么他到底有什么用呢?现在可以揭晓了:
////JavaSampler
public SampleResult sample(Entry entry) {
Arguments args = getArguments();
args.addArgument(TestElement.NAME, getName()); // Allow Sampler access
// to test element name
context = new JavaSamplerContext(args);
if (javaClient == null) {
log.debug(whoAmI() + "\tCreating Java Client");
javaClient = createJavaClient();
javaClient.setupTest(context);
}
SampleResult result = javaClient.runTest(context);
// Only set the default label if it has not been set
if (result != null && result.getSampleLabel().length() == 0) {
result.setSampleLabel(getName());
}
return result;
}
private JavaSamplerClient createJavaClient() {
if (javaClass == null) { // failed to initialise the class
return new ErrorSamplerClient();
}
JavaSamplerClient client;
try {
client = (JavaSamplerClient) javaClass.newInstance();
if (log.isDebugEnabled()) {
log.debug(whoAmI() + "\tCreated:\t" + getClassname() + "@"
+ Integer.toHexString(client.hashCode()));
}
if(isToBeRegistered) {
TEAR_DOWN_SET.add(this);
}
} catch (Exception e) {
log.error(whoAmI() + "\tException creating: " + getClassname(), e);
client = new ErrorSamplerClient();
}
return client;
}
其实没什么神奇的,读代码可以得到几点信息:
1) 通过HashTree中配置的classname,反射调用构造方法得到一个实例
2)该类是客户端提供的,而且必须是JavaSamplerClient类型
3)每次Sample时,JavaSamplerClient#runTest会被执行
这些扩展点为进一步集成提供了很好的线索,这里不展开,继续沿着JMeterThread#run思路,sampleOccurred产生一个SampleResult之后,所有的SampleListener都会被触发,即SampleListener#sampleOccurred(event)方法会被调用,再看本文开头的类图,也就是说ResultCollector#sampleOccurred(event)会执行:
@Override
public void sampleOccurred(SampleEvent event) {
SampleResult result = event.getResult();
if (isSampleWanted(result.isSuccessful())) {
sendToVisualizer(result);
if (out != null && !isResultMarked(result) && !this.isStats) {
SampleSaveConfiguration config = getSaveConfig();
result.setSaveConfig(config);
try {
if (config.saveAsXml()) {
SaveService.saveSampleResult(event, out);
} else { // !saveAsXml
String savee = CSVSaveService.resultToDelimitedString(event);
out.println(savee);
}
} catch (Exception err) {
log.error("Error trying to record a sample", err); // should throw exception back to caller
}
}
}
if(summariser != null) {
summariser.sampleOccurred(event);
}
}
可以看到,ResultCollector会去保存xml或者csv格式的测试结果文件,还会触发汇总Summariser.sampleOccurred(event),另外还有GUI上的显示等等,这些其实已经不是太重要了,因为实际测试中很可能是一个集群的环境,测试结果可能需要通过Remote写到中央测试机上。也就是说实现自己的ResultCollector不可避免的。
所有的JMeterThread结束之后,回到StandardJMeterEngine#run()最后一行notifyTestListenersOfEnd(testListeners),TestStateListener(ResultCollector, JavaSampler, TestPlan)的testEnded又被触发:
1)TestPlan#testEnded(): 关闭测试开始时候打开的文件
2)ResultCollector#testEnded():写文件结束符(xml的话必须谢结束的tag </...>),关闭stream,file等
3)若实现了teardownTest方法,则调用JavaSampleClient#testdownTest(JavaSamplerContext)
到此,JMeter的大致的生命周期介绍完毕,当然不是全部的生命周期都涵盖在这篇文章里了,比如在上一篇讲到过,JMeterThread运行结束退出前有个回调JMeterThreadMonitor#threadFinished(JMeterThread)在这里没有提及,这个JMeterThreadMonitor接口的实现类主要就是ThreadGroup。可以看前几篇文章去了解。
- 大小: 9.4 KB
- 大小: 52.1 KB
分享到:
相关推荐
在"jmeter-ssh-sampler-master.zip"这个压缩包中,我们主要探讨的是如何使用JMeter SSH Sampler来连接并操作Linux系统。 首先,SSH(Secure Shell)是一种网络协议,用于在不安全的网络上提供安全的远程登录和其他...
将 jpgc-graphs-basic-2.0.zip 解压缩后只有一个 lib 目录,该目录下有一个 ext 文件夹和一个 jmeter-plugins-cmn-jmeter-0.3.jar 包,ext 文件夹中有 jmeter-plugins-graphs-basic-2.0.jar 和 jmeter-plugins-...
https://blog.csdn.net/qq355667166/article/details/78914453),经过测试同学选型最终确认了采用jmeter+插件化jmeter-plugins-for-apache-dubbo(https://github.com/thubbo/jmeter-plugins-for-apache-dubbo)的...
Apache jmeter jmeter-plugins-cmn-jmeter-0.6.jar 下载
本文将深入探讨“jmeter-plugins-dubbo-2.7.1-jar-with-dependencies”这一系统压测工具包,它专门针对基于Java的Dubbo服务进行性能测试。了解并熟练掌握这一工具,能帮助我们更好地优化服务性能,提升系统的稳定性...
jmeter的dubbo插件,jmeter-plugins-dubbo-2.7.8-jar-with-dependencies.jar,适用于JMeter5.4.1版本,将解压后的文件jmeter-plugins-dubbo-2.7.8-jar-with-dependencies放在Jmeter安装目录下的\lib\ext文件夹中,...
本文将深入探讨"jmeter-plugins-dubbo-2.7.1-jar-with-dependencies (1)"这个压缩包中的关键知识点。 1. **JMeter Plugins for Dubbo** JMeter Plugins for Dubbo 是一个扩展了JMeter功能的插件,专门用于测试基于...
apache-jmeter-5.6.3.zip apache-jmeter-5.6.3.tgz apache-jmeter-5.6.3_src.zip apache-jmeter-5.6.3_src.tgz
jmeter-plugins-dubbo-2.7.1-jar-with-dependencies 2.jar jmeter本身并不支持dubbo接口的测试,需要下载第三方插件,然后将jar包放入${JMETER_HOME}\lib\ext路径下,重启即可。
jmeter-plugins-dubbo with-dependencies jmeter-plugins-dubbo-2.7.7-jar-with-dependencies.jar
4个jmeter测试报告模板集合 jmeter.results.shanhe.me.xsl jmeter.results.zyanycall.me.xsl jmeter-results-detail-report_30.xsl jmeter-results-report_21.xsl
《JMeter管理插件——jmeter-plugins-manager-1.7.jar深度解析》 Apache JMeter是一款功能强大的性能测试工具,广泛应用于Web应用、FTP服务器、数据库等服务的压力测试。为了扩展JMeter的功能,社区开发了各种插件...
【JMeter】JMeter插件管理插件:jmeter-plugins-manager-1.3.jar Apache JMeter是一款开源的性能测试工具,广泛应用于Web应用、FTP服务器、数据库等服务的负载和压力测试。JMeter的强大之处在于其丰富的插件生态...
jmeter-plugins-graphs-basic-2.0.jar是jmeter性能测试图形化显示插件
3. **监听器(Listeners)**:收集并显示测试结果,包括聚合报告、视图结果树、响应时间图等,其中"jmeter-results-detail-report"就是一种监听器,提供了详细的性能数据。 4. **断言(Assertions)**:检查服务器的...
"jmeter-plugins-manager-1.4下载" 提供的是JMeter的插件管理器,它极大地简化了JMeter第三方插件的安装和更新过程。下面将详细介绍JMeter、插件管理器及其使用方法。 1. JMeter简介: Apache JMeter是一款纯Java...
本文将详细介绍"jmeter-plugins-manager-1.3.jar.zip"的安装过程以及其功能和使用方法。 首先,我们来看"jmeter-plugins-manager-1.3.jar.zip"这个压缩包。它包含了JMeter Plugins Manager的1.3版本,这是一个帮助...
Apache JMeter (apache-jmeter-5.5.zip)可用于测试静态和动态资源、Web 动态应用程序的性能。 它可用于模拟服务器、服务器组、网络或对象上的重负载,以测试其强度或分析不同负载类型下的整体性能。 Apache JMeter...
拷贝jmeter-parallel-0.9.jar到Jmeter/lib/ext上。 启动Jmeter。 根据需要添加Parallel Controller: 1)在Jmeter的线程组下面的逻辑控制器,选择bzm并行控制器; 2)把浏览器或者wireShark观察到的同一批次的并发...
其中,`jmeter-plugins-manager-1.4.jar`是JMeter的插件管理器,它为用户提供了方便的方式来安装、更新和管理JMeter的各种插件。本文将详细介绍这个插件及其功能。 一、JMeter Plugins Manager的安装与使用 1. **...