之前做app的接口压力测试,每个接口都单独改参数运行保存结果,这样麻烦也没什么意义,昨天又叫我压测管理系统的接口,想着我不要再一个一个的加了,然后就各种奇思妙想的,最终不负有心人实现了。
实现方案
由于jmeter有一种方案是通过命令行执行的,就想着用java代码执行cmd命令来控制jmeter。经过一番云雨挣扎,最终实现了,代码很丑,不喜勿喷,有好的方案请给直接怼,在下好修改,成长
效果截图:
运行结果自动保存在文本中,具体如何分析就交给后台把,把着重异常的单独列出来就万事大吉 ok
代码:
package com.dahai.demo;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
private static String scriptFile = "D:\\jmeter-data\\web\\员工管理列表.jmx";
private static String logFile = "D:\\jmeter-data\\web\\员工管理列表.log";
private static String tmpFile = "D:\\jmeter-data\\web\\tmpFile.jmx";
public static void main(String[] args) throws Exception {
int count = 100;
int sec = 1;
System.out.println("开始启动:"+getCurrDate());
while (true) {
parse(String.valueOf(count),String.valueOf(sec));
String cmd = "D:\\apache-jmeter-5.1\\bin\\jmeter.bat -n -t " + tmpFile;
try {
Process ps = Runtime.getRuntime().exec(cmd);
BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));
String result = "";
String line;
while ((line = br.readLine()) != null) {
if (line.contains("summary =")) {
result = line;
}
}
saveLog(result,count,sec);
String err = result.split("Err:")[1].trim();
String s = err.substring(0, 1);
if (Integer.valueOf(s)>0) {
if (sec<=10) {
sec ++;
} else if (sec<=30) {
sec += 3;
} else {
sec += 5;
}
} else {
if (count<=1000) {
count = count + 100;
} else if (count<=3000) {
count = count + 300;
} else {
count = count + 500;
}
}
System.out.println("一个周期: "+getCurrDate());
if (sec>61) {
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("结束:"+getCurrDate());
}
private static void saveLog(String result,int count,int sec) throws Exception {
File file = new File(logFile);
result = "执行线程数:" + count + " 时间:" + sec + "s " + result;
OutputStreamWriter bo = new OutputStreamWriter(new FileOutputStream(file, true));
BufferedWriter writer = new BufferedWriter(bo);
writer.write(result);
writer.newLine();
writer.flush();
writer.close();
System.out.println(result);
}
public static void parse(String count,String sec) throws Exception {
if (new File(tmpFile).exists()) {
new File(tmpFile).delete();
}
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(scriptFile)));
OutputStreamWriter bo = new OutputStreamWriter(new FileOutputStream(tmpFile, true));
String line;
while ((line = br.readLine()) != null) {
if (line.contains("ThreadGroup.num_threads")) {
line = replaceNum(line,count);
} else if (line.contains("ThreadGroup.ramp_time")) {
line = replaceNum(line,sec);
}
bo.write(line);
bo.write("\n");
bo.flush();
}
br.close();
bo.close();
}
/**
* 替换数字
* @param value
* @param number
*/
private static String replaceNum(String value,String number) {
Pattern p = Pattern.compile("[\\d]");
Matcher matcher = p.matcher(value);
String result = matcher.replaceAll("&");
String[] split = result.split("&");
return split[0] + number + split[split.length - 1];
}
private static String getCurrDate() {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return format.format(new Date());
}
}
接下来我们要做的就是在jmeter中创建好要压测的接口,保存下来丢到代码里自己跑,也可以再加一个循环,把要测的接口保存到一个数组中依次进行 ?