欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

手寫java性能測試框架的實現(xiàn)示例

 更新時間:2022年07月21日 15:16:54   作者:FunTester  
這篇文章主要為大家介紹了java實現(xiàn)性能測試框架示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

之前寫過一個性能測試框架,只是針對單一的HTTP接口的測試,對于業(yè)務接口和非HTTP接口還無非適配,剛好前端時間工作中用到了,就更新了自己的測試框架,這次不再以請求為基礎,而是以方法為基礎,這樣就可以避免了單一性,有一個base類,然后其他的各種單一性請求在單獨寫一個適配類就好了,如果只是臨時用,直接重新實現(xiàn)base即可。

代碼分享

package com.fun.frame.thead;
import com.fun.frame.SourceCode;
import com.fun.frame.excute.Concurrent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import static com.fun.utils.Time.getTimeStamp;
/**
 * 多線程任務基類,可單獨使用
 */
public abstract class ThreadBase<T> extends SourceCode implements Runnable {
    private static final Logger logger = LoggerFactory.getLogger(ThreadBase.class);
    /**
     * 任務請求執(zhí)行次數(shù)
     */
    public int times;
    /**
     * 計數(shù)鎖
     * <p>
     * 會在concurrent類里面根據(jù)線程數(shù)自動設定
     * </p>
     */
    CountDownLatch countDownLatch;
    /**
     * 用于設置訪問資源
     */
    public T t;
    public ThreadBase(T t) {
        this();
        this.t = t;
    }
    public ThreadBase() {
        super();
    }
    /**
     * groovy無法直接訪問t,所以寫了這個方法
     *
     * @return
     */
    public String getT() {
        return t.toString();
    }
    @Override
    public void run() {
        try {
            before();
            List<Long> t = new ArrayList<>();
            long ss = getTimeStamp();
            for (int i = 0; i < times; i++) {
                long s = getTimeStamp();
                doing();
                long e = getTimeStamp();
                t.add(e - s);
            }
            long ee = getTimeStamp();
            logger.info("執(zhí)行次數(shù):{},總耗時:{}", times, ee - ss);
            Concurrent.allTimes.addAll(t);
        } catch (Exception e) {
            logger.warn("執(zhí)行任務失?。?, e);
        } finally {
            after();
            if (countDownLatch != null)
                countDownLatch.countDown();
        }
    }
    /**
     * 運行待測方法的之前的準備
     */
    protected abstract void before();
    /**
     * 待測方法
     *
     * @throws Exception
     */
    protected abstract void doing() throws Exception;
    /**
     * 運行待測方法后的處理
     */
    protected abstract void after();
    public void setCountDownLatch(CountDownLatch countDownLatch) {
        this.countDownLatch = countDownLatch;
    }
    public void setTimes(int times) {
        this.times = times;
    }
}

基礎類實現(xiàn)

下面是幾個實現(xiàn)過的基礎類:

package com.fun.frame.thead;
import com.fun.httpclient.ClientManage;
import com.fun.httpclient.FanLibrary;
import com.fun.httpclient.GCThread;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
/**
 * http請求多線程類
 */
public class RequestThread extends ThreadBase {
    static Logger logger = LoggerFactory.getLogger(RequestThread.class);
    /**
     * 請求
     */
    public HttpRequestBase request;
    /**
     * 單請求多線程多次任務構造方法
     *
     * @param request 被執(zhí)行的請求
     * @param times   每個線程運行的次數(shù)
     */
    public RequestThread(HttpRequestBase request, int times) {
        this.request = request;
        this.times = times;
    }
    @Override
    public void before() {
        request.setConfig(FanLibrary.requestConfig);
        GCThread.starts();
    }
    @Override
    protected void doing() throws Exception {
        getResponse(request);
    }
    @Override
    protected void after() {
        GCThread.stop();
    }
    /**
     * 多次執(zhí)行某個請求,但是不記錄日志,記錄方法用 loglong
     * <p>此方法只適應與單個請求的重復請求,對于有業(yè)務聯(lián)系的請求暫時不能適配</p>
     *
     * @param request 請求
     * @throws IOException
     */
    void getResponse(HttpRequestBase request) throws IOException {
        CloseableHttpResponse response = ClientManage.httpsClient.execute(request);
        String content = FanLibrary.getContent(response);
        if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK)
            logger.warn("響應狀態(tài)碼:{},響應內容:{}", content, response.getStatusLine());
        if (response != null) response.close();
    }
}

數(shù)據(jù)庫的實現(xiàn)

package com.fun.frame.thead;
import com.fun.interfaces.IMySqlBasic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.SQLException;
/**
 * 數(shù)據(jù)庫多線程類
 */
public class QuerySqlThread extends ThreadBase {
    private static Logger logger = LoggerFactory.getLogger(QuerySqlThread.class);
    String sql;
    IMySqlBasic base;
    public QuerySqlThread(IMySqlBasic base, String sql, int times) {
        this.times = times;
        this.sql = sql;
        this.base = base;
    }
    @Override
    public void before() {
        base.getConnection();
    }
    @Override
    protected void doing() throws SQLException {
        base.excuteQuerySql(sql);
    }
    @Override
    protected void after() {
        base.mySqlOver();
    }
}

concurrent類

package com.fun.frame.excute;
import com.fun.bean.PerformanceResultBean;
import com.fun.frame.Save;
import com.fun.frame.SourceCode;
import com.fun.frame.thead.ThreadBase;
import com.fun.profile.Constant;
import com.fun.utils.Time;
import com.fun.utils.WriteRead;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Concurrent {
    private static Logger logger = LoggerFactory.getLogger(Concurrent.class);
    /**
     * 線程任務
     */
    public ThreadBase thread;
    public List<ThreadBase> threads;
    public int num;
    public static Vector<Long> allTimes = new Vector<>();
    ExecutorService executorService;
    CountDownLatch countDownLatch;
    /**
     * @param thread 線程任務
     * @param num    線程數(shù)
     */
    public Concurrent(ThreadBase thread, int num) {
        this(num);
        this.thread = thread;
    }
    /**
     * @param threads 線程組
     */
    public Concurrent(List<ThreadBase> threads) {
        this(threads.size());
        this.threads = threads;
    }
    public Concurrent(int num) {
        this.num = num;
        executorService = Executors.newFixedThreadPool(num);
        countDownLatch = new CountDownLatch(num);
    }
    /**
     * 執(zhí)行多線程任務
     */
    public PerformanceResultBean start() {
        long start = Time.getTimeStamp();
        for (int i = 0; i < num; i++) {
            ThreadBase thread = getThread(i);
            thread.setCountDownLatch(countDownLatch);
            executorService.execute(thread);
        }
        shutdownService(executorService, countDownLatch);
        long end = Time.getTimeStamp();
        logger.info("總計" + num + "個線程,共用時:" + Time.getTimeDiffer(start, end) + "秒!");
        return over();
    }
    private static void shutdownService(ExecutorService executorService, CountDownLatch countDownLatch) {
        try {
            countDownLatch.await();
            executorService.shutdown();
        } catch (InterruptedException e) {
            logger.warn("線程池關閉失敗!", e);
        }
    }
    private PerformanceResultBean over() {
        Save.saveLongList(allTimes, num);
        return countQPS(num);
    }
    ThreadBase getThread(int i) {
        if (threads == null) return thread;
        return threads.get(i);
    }
    /**
     * 計算結果
     * <p>此結果僅供參考</p>
     *
     * @param name 線程數(shù)
     */
    public static PerformanceResultBean countQPS(int name) {
        List<String> strings = WriteRead.readTxtFileByLine(Constant.LONG_Path + name + Constant.FILE_TYPE_LOG);
        int size = strings.size();
        int sum = 0;
        for (int i = 0; i < size; i++) {
            int time = SourceCode.changeStringToInt(strings.get(i));
            sum += time;
        }
        double v = 1000.0 * size * name / sum;
        PerformanceResultBean performanceResultBean = new PerformanceResultBean(name, size, sum / size, v);
        performanceResultBean.print();
        return performanceResultBean;
    }
}

redis實現(xiàn)類缺失,因為沒有遇到需要單獨實現(xiàn)的需求。

關于用代碼還是用工具實現(xiàn)并發(fā),我個人看法所有所長,單究其根本,必然是代碼勝于工具,原因如下:門檻高,適應性強;貼近開發(fā),利于調優(yōu)。

性能測試,并發(fā)只是開始,只有一個好的開始才能進行性能數(shù)據(jù)分析,性能參數(shù)調優(yōu)。所以不必拘泥于到底使用哪個工具那種語言,據(jù)我經(jīng)驗來說:基本的測試需求都是能滿足的,只是實現(xiàn)的代價不同。

groovy是一種基于JVM的動態(tài)語言,我覺得最大的優(yōu)勢有兩點

  • 第一:于java兼容性非常好,大部分時候吧groovy的文件后綴改成java直接可以用,反之亦然。java的絕大部分庫,groovy都是可以直接拿來就用的。這還帶來了另外一個有點,學習成本低,非常低,直接上手沒問題,可以慢慢學習groovy不同于Java的語法;
  • 第二:編譯器支持變得更好,現(xiàn)在用的intellij的ide,總體來說已經(jīng)比較好的支持groovy語言了,寫起代碼來也是比較順滑了,各種基于groovy的框架工具也比較溜,特別是Gradle構建工具,比Maven爽很多。

以上就是java性能測試框架手寫實現(xiàn)示例的詳細內容,更多關于java 性能測試框架的資料請關注腳本之家其它相關文章!

相關文章

  • springboot如何根據(jù)不同的日志級別顯示不同的顏色

    springboot如何根據(jù)不同的日志級別顯示不同的顏色

    這篇文章主要介紹了springboot如何根據(jù)不同的日志級別顯示不同的顏色問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • java中char類型轉換成int類型的2種方法

    java中char類型轉換成int類型的2種方法

    這篇文章主要給大家介紹了關于java中char類型轉換成int類型的2種方法,因為java是一門強類型語言,所以在數(shù)據(jù)運算中會存在類型轉換,需要的朋友可以參考下
    2023-07-07
  • Spring?MVC中的攔截器案例演示

    Spring?MVC中的攔截器案例演示

    攔截器可以攔截所有的請求,也可以只攔截滿足指定的請求,?Spring?MVC?的攔截器類似于過濾器,用來執(zhí)行預處理和后處理操作,本文給大家介紹Spring?MVC中的攔截器案例演示,感興趣的朋友跟隨小編一起看看吧
    2023-10-10
  • 很多人竟然不知道Java線程池的創(chuàng)建方式有7種

    很多人竟然不知道Java線程池的創(chuàng)建方式有7種

    本文主要介紹了很多人竟然不知道Java線程池的創(chuàng)建方式有7種,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Java注解詳細介紹

    Java注解詳細介紹

    這篇文章主要介紹了Java注解詳細介紹,本文講解了Java注解是什么、Java注解基礎知識、Java注解類型、定義Java注解類型的注意事項等內容,需要的朋友可以參考下
    2014-09-09
  • IDEA使用SequenceDiagram插件繪制時序圖的方法

    IDEA使用SequenceDiagram插件繪制時序圖的方法

    這篇文章主要介紹了IDEA使用SequenceDiagram插件繪制時序圖的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • 解讀@NotNull和@NonNull的區(qū)別及使用

    解讀@NotNull和@NonNull的區(qū)別及使用

    這篇文章主要介紹了解讀@NotNull和@NonNull的區(qū)別及使用,具有很好的參考價值,希望對大家有所幫助。
    2023-01-01
  • java解決單緩沖生產(chǎn)者消費者問題示例

    java解決單緩沖生產(chǎn)者消費者問題示例

    這篇文章主要介紹了java解單緩沖生產(chǎn)者消費者問題示例,需要的朋友可以參考下
    2014-04-04
  • SpringBoot中Date格式化處理的三種實現(xiàn)

    SpringBoot中Date格式化處理的三種實現(xiàn)

    Spring Boot作為一個簡化Spring應用開發(fā)的框架,提供了多種處理日期格式化的方法,本文主要介紹了SpringBoot中Date格式化處理實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • Java字符串拼接的優(yōu)雅方式實例詳解

    Java字符串拼接的優(yōu)雅方式實例詳解

    字符串拼接一般使用“+”,但是“+”不能滿足大批量數(shù)據(jù)的處理,下面這篇文章主要給大家介紹了關于Java字符串拼接的幾種優(yōu)雅方式,需要的朋友可以參考下
    2021-07-07

最新評論