`
songzi0206
  • 浏览: 158770 次
  • 性别: Icon_minigender_1
  • 来自: 上海
博客专栏
Group-logo
All are from ...
浏览量:33800
Group-logo
Programming w...
浏览量:19666
社区版块
存档分类
最新评论

Programming with JMeter-- ThreadGroup

阅读更多

       项目搞一段落,总算有时间回来继续。

      上一篇写到JMeterEngine会驱动JMeter ThreadGroup启动Test Threads 执行测试,其本身也是一个Runnable,这里把测试驱动(JUnit或者其他类似main之类的)看作主线程(main thread)的话, JMeterEngine作为第一层子线程(First Child Thread),所以如果项目代码基于很多模块(比如基于OSGI),需要进行ClassLoader调整的话可以重写JMeterEngine的runTest方法,例如.:

                @Override
		public void runTest() throws JMeterEngineException
		{
			try {
				tcClassloader = Thread.currentThread().getContextClassLoader();

				Future<?> f = DefaultExecutorService.getInstance().submit(this);
				f.get();
			}
			catch (Exception err) {
				stopTest();
				throw new JMeterEngineException(err);
			}
			finally {
				
			}
		}

                @Override
		public void run()
		{
			ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
			Thread.currentThread().setContextClassLoader(tcClassloader);
			try {
				super.run();
			}
			finally {
				Thread.currentThread().setContextClassLoader(oldCl);
			}
		}

 

       JMeterEngine从JMeter的数据结构HashTree中取得ThreadGroup之后,通过ThreadGroup的API: start / stopThread / waitThreadsStopped / tellThreadsToStop /  numberOfActiveThreads / verifyThreadsStopped 进行测试线程的开始 / 结束,并在相应的阶段通知一些监听器,而真正创建和启动Test Threads的地方是ThreadGroup。看ThreadGroup#start(int groupCount, ListenerNotifier notifier, ListedHashTree threadGroupTree, StandardJMeterEngine engine)方法,有两种启动线程的方式:

1) 如果是dealyedStartup,即HashTree中配置了ThreadGroup.delayedStart为true,ThreadGroup会交给内部类ThreadStart来创建/启动测试线程。ThreadStart作为一个单独的线程,会计算每一个测试线程的delay time,duration time,end time,根据这些time值创建 / 开始 / 结束 测试线程。

       我们知道JMeter中对线程Stop Condition 提供一些默认的选择:LoopController, IfController, RunTime等。当我们需要 ”执行测试 一段时间停止“ 这样的场景时,往往需要选择org.apache.jmeter.control.RunTime对每一个线程的循环进行控制。而如果在线程启动阶段endTime已经过时的话,就没有必要再启动测试线程了。

 

2) 若不是dealyedStartup,就创建并启动所有测试线程。

      

       ThreadGroup是一个很重要的扩展点,一放面实际项目往往有很多资源需要整合,例如项目中有自己实现统一的线程池,有特定的服务器等等,另一方面对于两种线程启动模式略显复杂,尤其是当出现class load出问题,我们需要控制线程上下文classloader的时候,所以实际项目中重写ThreadGroup往往合并一种模式就够了。以本人个例,需要整合weblogic统一的WorkManager进行线程调度,区分 Remote和Local 的测试线程,大概可以这样参考(略去部分业务相关代码)

 

 ThreadGroup#start:

        @Override
	public void start(int groupCount, ListenerNotifier notifier, ListedHashTree threadGroupTree, StandardJMeterEngine engine)
	{
		running = true;
		int numThreads = getNumThreads();
		int rampUp = getRampUp();
		double perThreadDelay = rampUp * 1000.0 / getNumThreads();
		log.info("Starting thread group number " + groupCount + " threads " + numThreads);

		final JMeterContext context = JMeterContextService.getContext();
		long now = System.currentTimeMillis();
		for (int i = 0; running && i < numThreads; i++) {
			final CustomJMeterThread jmThread = makeThread(groupCount, notifier, threadGroupTree, engine, i, context);
			jmThread.setInitialDelay((int) (i * perThreadDelay));
			scheduleThread(jmThread, now);
                        //ITestResourceHolder:自定义接口用来存放一些共用的测试变量,重写JMeterEngine时顺便实现了该接口,故可在此拿到很多需要的东西
			final ITestResourceHolder resourceHolder = (ITestResourceHolder) engine;
			Runnable runnable = null;
			switch ((TestType) resourceHolder.getResourceMap().get(TestType.class.getName())) {
				case LOCAL:
					runnable = new DaemonizableNamedRunnable() {
						@Override
						public String getName()
						{
							return jmThread.getThreadName();
						}
						@Override
						public boolean isDaemon()
						{
							return true;
						}
						@Override
						public void release()
						{}
						@Override
						public void run()
						{
							jmThread.run();
						}
					};
					break;
				case REMOTE:
					final Subject subj = Security.getCurrentSubject();
					runnable = new DaemonizableNamedRunnable() {
						@Override
						public String getName()
						{
							return jmThread.getThreadName();
						}
						@Override
						public boolean isDaemon()
						{
							return true;
						}
						@Override
						public void release()
						{}

						@Override
						public void run()
						{
							Security.runAs(subj, new PrivilegedAction<Void>() {

								@Override
								public Void run()
								{
									jmThread.run();
									return null;
								}
							});
						}
					};
					break;
			}
			Future<?> f = DefaultExecutorService.getInstance().submit(runnable);
			allThreads.put(jmThread, f);
		}
		log.info("Started thread group number " + groupCount);
	}

 

      start已经重写,stop之类相关的也要相应重写:

     

/* (non-Javadoc)
	* @see org.apache.jmeter.threads.ThreadGroup#stop()
	*/
	@Override
	public void stop()
	{
		running = false;
		for (JMeterThread item : allThreads.keySet()) {
			item.stop();
		}
	}

	/* (non-Javadoc)
	 * @see org.apache.jmeter.threads.ThreadGroup#tellThreadsToStop()
	 */
	@Override
	public void tellThreadsToStop()
	{
		running = false;
		for (Entry<JMeterThread, Future<?>> entry : allThreads.entrySet()) {
			JMeterThread item = entry.getKey();
			item.stop(); // set stop flag
			item.interrupt(); // interrupt sampler if possible
			Future<?> f = entry.getValue();
			if (f != null) {
				f.cancel(true);
				allThreads.remove(item);
			}
		}
	}

/* (non-Javadoc)
	 * @see org.apache.jmeter.threads.ThreadGroup#waitThreadsStopped()
	 */
	@Override
	public void waitThreadsStopped()
	{
		for (Future<?> f : allThreads.values()) {
			try {
				if (getDuration() > 0) {
					f.get(getDuration(), TimeUnit.SECONDS);
				}
				else {
					f.get();
				}
			}
			catch (InterruptedException e) {
				return;
			}
			catch (ExecutionException e) {
				log.error("Exception occurred when try to retrive future value from JMeterThread ", e);
			}
			catch (TimeoutException e) {
				tellThreadsToStop();
				return;
			}
		}
		allThreads.clear();
	}

 

 

分享到:
评论

相关推荐

    jmeter-plugins-cmn-jmeter-0.3

    将 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-...

    jmeter-plugins-dubbo-2.7.4-jar-with-dependencies.jar

    https://blog.csdn.net/qq355667166/article/details/78914453),经过测试同学选型最终确认了采用jmeter+插件化jmeter-plugins-for-apache-dubbo(https://github.com/thubbo/jmeter-plugins-for-apache-dubbo)的...

    jmeter-plugins-cmn-jmeter-0.6.jar

    Apache jmeter jmeter-plugins-cmn-jmeter-0.6.jar 下载

    jmeter-plugins-dubbo-2.7.1-jar-with-dependencies

    本文将深入探讨“jmeter-plugins-dubbo-2.7.1-jar-with-dependencies”这一系统压测工具包,它专门针对基于Java的Dubbo服务进行性能测试。了解并熟练掌握这一工具,能帮助我们更好地优化服务性能,提升系统的稳定性...

    jmeter-plugins-dubbo-2.7.8-jar-with-dependencies.jar

    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文件夹中,...

    apache-jmeter-5.6.3

    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 (1)

    本文将深入探讨"jmeter-plugins-dubbo-2.7.1-jar-with-dependencies (1)"这个压缩包中的关键知识点。 1. **JMeter Plugins for Dubbo** JMeter Plugins for Dubbo 是一个扩展了JMeter功能的插件,专门用于测试基于...

    jmeter-plugins-dubbo-2.7.1-jar-with-dependencies.jar.zip

    jmeter-plugins-dubbo-2.7.1-jar-with-dependencies 2.jar jmeter本身并不支持dubbo接口的测试,需要下载第三方插件,然后将jar包放入${JMETER_HOME}\lib\ext路径下,重启即可。

    jmeter-plugins-dubbo-2.7.7-jar-with-dependencies.jar

    jmeter-plugins-dubbo with-dependencies jmeter-plugins-dubbo-2.7.7-jar-with-dependencies.jar

    jmeter-results-report.zip|jmeter-results-report_21.xsl

    4个jmeter测试报告模板集合 jmeter.results.shanhe.me.xsl jmeter.results.zyanycall.me.xsl jmeter-results-detail-report_30.xsl jmeter-results-report_21.xsl

    jmeter-plugins-manager-1.7.jar JMeter 管理插件

    《JMeter管理插件——jmeter-plugins-manager-1.7.jar深度解析》 Apache JMeter是一款功能强大的性能测试工具,广泛应用于Web应用、FTP服务器、数据库等服务的压力测试。为了扩展JMeter的功能,社区开发了各种插件...

    jmeter-plugins-graphs-basic-2.0.jar

    jmeter-plugins-graphs-basic-2.0.jar是jmeter性能测试图形化显示插件

    【jmeter】jmeter-plugins-manager-1.3.jar下载

    【JMeter】JMeter插件管理插件:jmeter-plugins-manager-1.3.jar Apache JMeter是一款开源的性能测试工具,广泛应用于Web应用、FTP服务器、数据库等服务的负载和压力测试。JMeter的强大之处在于其丰富的插件生态...

    Apache JMeter (apache-jmeter-5.5.zip)

    Apache JMeter (apache-jmeter-5.5.zip)可用于测试静态和动态资源、Web 动态应用程序的性能。 它可用于模拟服务器、服务器组、网络或对象上的重负载,以测试其强度或分析不同负载类型下的整体性能。 Apache JMeter...

    jmeter-parallel-0.9.jar

    拷贝jmeter-parallel-0.9.jar到Jmeter/lib/ext上。 启动Jmeter。 根据需要添加Parallel Controller: 1)在Jmeter的线程组下面的逻辑控制器,选择bzm并行控制器; 2)把浏览器或者wireShark观察到的同一批次的并发...

    jmeter-results-detail-report_30.rar

    标题 "jmeter-results-detail-report_30.rar" 暗示了这可能是一个使用Apache JMeter工具进行性能测试后的结果报告。JMeter是一款开源、Java编写的负载和性能测试工具,广泛应用于Web应用的压力测试。这个压缩包很...

    jmeter-plugins-manager-1.4.jar插件

    其中,`jmeter-plugins-manager-1.4.jar`是JMeter的插件管理器,它为用户提供了方便的方式来安装、更新和管理JMeter的各种插件。本文将详细介绍这个插件及其功能。 一、JMeter Plugins Manager的安装与使用 1. **...

    jmeter-plugins-extras-libs-1.1.3,jmeter-plugins-standard-1.1.3

    本文将深入探讨"jmeter-plugins-extras-libs-1.1.3"和"jmeter-plugins-standard-1.1.3"这两个版本的插件,解析它们的核心价值和应用场景。 首先,我们关注"jmeter-plugins-extras-libs-1.1.3"。这个名字中的"extras...

    jmeter-plugins-manager-1.3.jar.zip

    本文将详细介绍"jmeter-plugins-manager-1.3.jar.zip"的安装过程以及其功能和使用方法。 首先,我们来看"jmeter-plugins-manager-1.3.jar.zip"这个压缩包。它包含了JMeter Plugins Manager的1.3版本,这是一个帮助...

    apache-jmeter-5.2.1--.zip

    在这个"apache-jmeter-5.2.1--.zip"压缩包中,包含了JMeter 5.2.1版本的完整安装文件。这个版本是在JMeter的长期发展过程中的一个重要里程碑,它提供了许多新功能、改进和错误修复,以提升测试效率和准确性。 ...

Global site tag (gtag.js) - Google Analytics