美文网首页JAVA
简单多线程压测接口

简单多线程压测接口

作者: 秦时的明月夜 | 来源:发表于2019-07-30 11:06 被阅读0次

测试接口的性能

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class Test {

    //统计总消耗时间
    private static AtomicInteger sum = new AtomicInteger(0);
    //统计执行了多少次
    private static AtomicInteger count = new AtomicInteger(0);
    private static String SysLine = System.getProperty("line.separator");

    private static Logger log = LoggerFactory.getLogger(Test.class);

    public static void main(String[] args) {
            //存放token提供请求凭证
            List<String> tokenlist = new ArrayList<String>();
            //存放每次执行的时间
            List<Integer> timeList = new ArrayList<Integer>();
            String fileName = "token.txt";
            //读取参数
            tokenlist = readTxtLine(fileName);
            //线程数
            int threadCount = 20;
            //循环次数
            int num = 1;
            //固定的线程池
            ExecutorService pool = Executors.newFixedThreadPool(threadCount);
            //倒计数器
            CountDownLatch countDownLatch = new CountDownLatch(tokenlist.size() * num);
            for (int i = 0; i < num; i++) {
                tokenlist.forEach((token) -> {
                    System.out.println(token);
                    pool.submit(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                long time1 = System.currentTimeMillis();
                                //测试内容
                                testFunc();
                                long time2 = System.currentTimeMillis();
                                int time = (int) (time2 - time1);
                                sum.getAndAdd(time);
                                count.incrementAndGet();
                                timeList.add(time);
                            } catch (Exception e) {
                                log.error("sso test  error");
                            } finally {
                                countDownLatch.countDown();
                            }

                        }
                    });
                });
            }
            try {
                countDownLatch.await();
                pool.shutdownNow();
                writeTokenToTxt("", "time.txt", true);
                timeList.stream().forEach((time) -> {
                    String content = String.valueOf(time) + SysLine;
                    TestEnv1.writeTokenToTxt(content, "time.txt", false);
                });
                int maxTime = Collections.max(timeList);
                int minTime = Collections.min(timeList);
                log.info(SysLine
                       +"-----------总时间:" + sum.get()+"ms"+SysLine
                       +"-----------请求次数:" + count.get()+"次"+SysLine
                       +"-----------最大耗时:" + maxTime+"ms"+SysLine
                       +"-----------最小耗时:" + minTime+"ms"+SysLine
                       +"-----------平均每次请求时间:" + sum.get() * 1.000 / count.get()+"ms"+SysLine
                       +"-----------平均每秒请求次数:" + 1 / (sum.get() / 1000.000 / count.get())+"次/秒"+SysLine
                       +"-----------TPS:" + threadCount / (sum.get() * 1.000 / count.get() / 1000)+SysLine);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }


    /**
     * 读取文件中参数
     * @param fileName
     * @return
     */
    public static List<String>  readTxtLine(String fileName){
        Path file = Paths.get(fileName);
        List<String> tokenlist = new ArrayList<>();
        try {
            tokenlist = Files.readAllLines(file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return tokenlist;
    }

    /**
     * 测试方法
     */
    public static void testFunc(){
        log.info("这是测试方法");
    }


    /**
     * 将参数写入文件
     * @param content
     * @param fileName
     * @param clear
     */
    public static void writeTokenToTxt(String content,String fileName,boolean clear){
        RandomAccessFile randomFile = null;
        try {
            Path fpath = Paths.get(fileName);
            if(!Files.exists(fpath)) {
                try {
                    Files.createFile(fpath);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }else{
                if(clear){
                    Files.write(fpath,"".getBytes());
                }
            }
            randomFile = new RandomAccessFile(fileName, "rw");
            long fileLength = randomFile.length();
            randomFile.seek(fileLength);
            randomFile.writeBytes(content);
            randomFile.close();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(randomFile!=null){
                try {
                    randomFile.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

token.txt是一些测试数据记录到文本中,比如登录账号,或者请求的token,供测试方法 testFunc调用。(我测试的接口需要登录,所以我需要通过用户账号,获取用户的token,因为用户量比较大,需要保存到文件token.txt中,再读取文件 )

testFunc就是测试的方法,里面是详细的测试内容。代码中可以直接算出消耗的最大时间、最小时间、平均时间、和TPS。如果还需要其他参数的结果,可以把时间记录到文本中,我把每次执行的时间保存到time.txt中,后期我们可以操作文本,进行统计。使用脚本统计简单方便,awk工具就很好用。

对保存的时间可以坐统计分析

分组统计每个时间段的时间情况

cat  time.txt|awk '{   if($1>=0 && $1<10){m["01-10"]+=1}
                        else if($1>=10&&$1<30){m["10-30"]+=1}
                        else{m["30--"]+=1}
                   }
                  END{ for (k in m)  print k,"\t", m[k]}' |sort -nrk2 
###如果分组太多也可以使用head -n 20只显示前几行
.....(省略)m[k]}' |sort -nrk2|head -n 20
image.png

获取中位数

cat time.txt|sort -nk1|awk '{m[++n]=$1}END{  
      if(n%2==1) print m[int(n/2)];
      else print (m[n/2]+m[n/2+1])/2}' 
image.png
图中获取的中位数是8因此可以说明testFunc内容消耗时间8ms以下占了一半。

相关文章

  • 简单多线程压测接口

    测试接口的性能 token.txt是一些测试数据记录到文本中,比如登录账号,或者请求的token,供测试方法 te...

  • jmeter随手笔记 -- 跨线程组传参

    今天遇到一个场景,需要对一个支付接口进行压测,支付接口需要token才能请求成功,而压测是多线程把获取token接...

  • 流量录制,基于常态化压测

    简介 常态化压测、业务压测、集群压测、全链路压测、等基于特定需求的对后台接口进行的并发式请求,接口自动化压测数据的...

  • 四种方式实现HttpServer并测试负载能力

    1.ServerSocket实现httpServer 1.1 阻塞式 代码: 压测结果: 1.2 多线程 压测结...

  • Jmeter压测简单Java接口

    Jmeter Apache JMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试,...

  • 6.7-Jmeter5.x压测接口实战-接口性能优化前后QPS对

    Jmeter5.x压测接口实战-接口性能优化前后QPS对比 简介: Jmeter5.x压测接口实战-接口性能优化前...

  • JMeter简单的接口压测实战

    一、在JMeter界面进行测试需要测试的接口:/api/firm/search1、添加线程组Thread Grou...

  • jmeter压测

    jmeter压测 做压测的目的 找到功能的极限(然后进行代码优化或升级设备) 压测对象 挑选重要的接口进行测试,例...

  • 接口压测监控注意事项

    一、基于http请求的接口压测,在压测过程中,需要注意的监控地方有: 1、接口端的监控:a) RTmax, RT均...

  • jemter压测实操

    一. 确定压测内容 与开发确认需要压测的接口 检查接口是否有加密验签等,需提前处理 提前准备好所需的压测数据,比如...

网友评论

    本文标题:简单多线程压测接口

    本文链接:https://www.haomeiwen.com/subject/tykgrctx.html