相信一萬行代碼的理論!
上期將了多線程基類和執行類,本期分享一下兩種壓測模式。一種是定量,即單線程循環次數固定;另外一種是定時,即單線程執行時間固定。兩種方式各有優劣,實際工做中我的偏向定量,好處多多,比較好作任務管理,參數定製等等,缺點就是偏差相比定時較大,這一點能夠經過適當延長壓測次數達到。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(); } }