相信一万行代码的理论!
上期将了多线程基类和执行类,本期分享一下两种压测模式。一种是定量,即单线程循环次数固定;另外一种是定时,即单线程执行时间固定。两种方式各有优劣,实际工做中我的偏向定量,好处多多,比较好作任务管理,参数定制等等,缺点就是偏差相比定时较大,这一点能够经过适当延长压测次数达到。java
虽然两个都是虚拟类,可是基本功能已经所有完成,具有了进行压测的能力,下一期讲解两个基于HTTPrequestbase
对象的压测实现类以及链接资源回收多线程类的代码。git
性能测试系列视频以下:编程
过程当中还发现了小BUG
,已经修复,欢迎各位多提提意见,关注FunTester
交流测试相关。api
gitee地址:https://gitee.com/fanapi/tester网络
定量模式虚拟类:多线程
package com.fun.base.constaint; import com.fun.base.interfaces.MarkThread; import com.fun.config.HttpClientConstant; import com.fun.frame.excute.Concurrent; import com.fun.frame.httpclient.GCThread; import com.fun.utils.Time; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; /** * 请求时间限制的多线程类,限制每一个线程执行的次数 * * <p> * 一般在测试某项用例固定时间的场景下使用,能够提早终止测试用例 * </p> * * @param <T> 闭包参数传递使用,Groovy脚本会有一些兼容问题,部分对象须要tostring获取参数值 */ public abstract class ThreadLimitTimesCount<T> extends ThreadBase { private static final Logger logger = LoggerFactory.getLogger(ThreadLimitTimesCount.class); public List<String> marks = new ArrayList<>(); /** * 全局的时间终止开关 */ private static boolean key = false; /** * 任务请求执行次数 */ public int times; public ThreadLimitTimesCount(T t, int times, MarkThread markThread) { this.times = times; this.t = t; this.mark = markThread; } protected ThreadLimitTimesCount() { super(); } @Override public void run() { try { before(); List<Long> t = new ArrayList<>(); long ss = Time.getTimeStamp(); for (int i = 0; i < times; i++) { try { threadmark = mark == null ? EMPTY : this.mark.mark(this); long s = Time.getTimeStamp(); doing(); long e = Time.getTimeStamp(); excuteNum++; long diff = e - s; t.add(diff); if (diff > HttpClientConstant.MAX_ACCEPT_TIME) marks.add(diff + CONNECTOR + threadmark); if (status() || key) break; } catch (Exception e) { logger.warn("执行任务失败!", e); errorNum++; } } long ee = Time.getTimeStamp(); logger.info("执行次数:{},错误次数: {},总耗时:{} s", times, errorNum, (ee - ss) / 1000 + 1); Concurrent.allTimes.addAll(t); Concurrent.requestMark.addAll(marks); } catch (Exception e) { logger.warn("执行任务失败!", e); } finally { after(); } } /** * 运行待测方法的以前的准备 */ @Override public void before() { key = false; } @Override public boolean status() { return errorNum > 10; } /** * 用于在某些状况下提早终止测试 */ public static void stopAllThread() { key = true; } @Override protected void after() { super.after(); marks = new ArrayList<>(); GCThread.stop(); } }
定时模式虚拟类:闭包
package com.fun.base.constaint; import com.fun.base.interfaces.MarkThread; import com.fun.config.HttpClientConstant; import com.fun.frame.excute.Concurrent; import com.fun.frame.httpclient.GCThread; import com.fun.utils.Time; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; /** * 请求时间限制的多线程类,限制每一个线程执行的时间 * <p> * 一般在测试某项用例固定时间的场景下使用,能够提早终止测试用例 * </p> * * @param <T> 闭包参数传递使用,Groovy脚本会有一些兼容问题,部分对象须要tostring获取参数值 */ public abstract class ThreadLimitTimeCount<T> extends ThreadBase { private static final Logger logger = LoggerFactory.getLogger(ThreadLimitTimeCount.class); public List<String> marks = new ArrayList<>(); /** * 全局的时间终止开关 */ private static boolean key = false; /** * 任务请求执行时间,单位是秒 */ public int time; public ThreadLimitTimeCount(T t, int time, MarkThread markThread) { this.time = time * 1000; this.t = t; this.mark = markThread; } protected ThreadLimitTimeCount() { super(); } @Override public void run() { try { before(); List<Long> t = new ArrayList<>(); long ss = Time.getTimeStamp(); long et = ss; while (true) { try { threadmark = mark == null ? EMPTY : this.mark.mark(this); long s = Time.getTimeStamp(); doing(); et = Time.getTimeStamp(); excuteNum++; long diff = et - s; t.add(diff); if (diff > HttpClientConstant.MAX_ACCEPT_TIME) marks.add(diff + CONNECTOR + threadmark); if ((et - ss) > time || status() || key) break; } catch (Exception e) { logger.warn("执行任务失败!", e); errorNum++; } } long ee = Time.getTimeStamp(); logger.info("执行次数:{}, 失败次数: {},总耗时: {} s", excuteNum, errorNum, (ee - ss) / 1000 + 1); Concurrent.allTimes.addAll(t); Concurrent.requestMark.addAll(marks); } catch (Exception e) { logger.warn("执行任务失败!", e); } finally { after(); } } /** * 用于在某些状况下提早终止测试 */ public static void stopAllThread() { key = true; } public boolean status() { return errorNum > 10; } /** * 运行待测方法的以前的准备 */ @Override public void before() { key = false; } @Override protected void after() { super.after(); marks = new ArrayList<>(); GCThread.stop(); } }