测试接口的性能
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
以下占了一半。
网友评论