定時和定量壓測模式實現--視頻講解

相信一萬行代碼的理論!

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


}

  • 鄭重聲明:「FunTester」首發,歡迎關注交流,禁止第三方轉載。

技術類文章精選

無代碼文章精選

相關文章
相關標籤/搜索