写点什么

架构师训练营 - 第七周 - 作业

用户头像
韩挺
关注
发布于: 2020 年 07 月 21 日

用你熟悉的编程语言写一个 web 性能压测工具,输入参数:URL,请求总次数,并发数。输出参数:平均响应时间,95% 响应时间。用这个测试工具以 10 并发、100 次请求压测

public class JavaPerformanceTest {
//超时请求时间
private final long TIMEOUT = 3000;
//超时请求时间单位
private final TimeUnit UNIT = TimeUnit.MILLISECONDS;
//默认总共请求数
private int totalNums = 100;
//默认并发数
private int concurrentNums = 10;

public static void main(String[] args) {
JavaPerformanceTest javaTest = new JavaPerformanceTest();
javaTest.test(args);

}

private void test(String[] args) {
try {
//测试地址
String url = "https://www.baidu.com/";
//封装为URL类
final URL rea = new URL(url);
//总共请求数
totalNums = 100;
//并发数
concurrentNums = 10;

//模拟请求
List<Future<RequestResult>> futureList = simulateRequest(rea);
//结果展示
display(futureList);


} catch (Exception ex) {
ex.printStackTrace();
}
}

/**
* 模拟请求
*
* @param rea
* @throws InterruptedException
*/
private List<Future<RequestResult>> simulateRequest(URL rea)
throws InterruptedException {

int seconds = totalNums % concurrentNums == 0
? totalNums / concurrentNums
: totalNums / concurrentNums + 1;

ExecutorService service = Executors.newFixedThreadPool(seconds);
List<Callable<RequestResult>> requestList = new ArrayList<>();
List<Future<RequestResult>> futureList = new ArrayList<>();
for (int i = 0; i < seconds; i++) {
requestList.clear();
//当前需要请求数
int curConcurrentNums = (i == seconds - 1)
? totalNums - concurrentNums * i
: concurrentNums;

for (int j = 0; j < curConcurrentNums; j++) {
requestList.add(() -> req(rea));
}
List<Future<RequestResult>> futures = service.invokeAll(requestList, TIMEOUT, UNIT);
futureList.addAll(futures);
//间隔一秒
Thread.sleep(1000);
}
service.shutdown();

return futureList;
}

/**
* 输出结果
*
* @param futureList
*/
private void display(List<Future<RequestResult>> futureList) {
List<Long> times = new ArrayList<>();
int errorNums = 0;
for (Future<RequestResult> resultSetFutureTask : futureList) {
try {
RequestResult requestResult=resultSetFutureTask.get();
if(requestResult.code==200) {
times.add(requestResult.elapsedTime);
}else{
//作为错误数据统计
errorNums++;
}
} catch (InterruptedException ex) {
//作为错误数据统计
errorNums++;
} catch (ExecutionException ex) {
//作为错误数据统计
errorNums++;
}
}
//输出结果
times.sort(Long::compareTo);
System.out.println("平均响应时间:" + times.stream().mapToLong(p -> p.longValue()).sum() / totalNums);
System.out.println("90% 响应时间:" + times.get(totalNums * 90 / 100));
System.out.println("95% 响应时间:" + times.get(totalNums * 95 / 100));
System.out.println("99% 响应时间:" + times.get(totalNums * 99 / 100));
System.out.println("最小响应时间:" + times.get(0));
System.out.println("最大响应时间:" + times.get(totalNums - 1));
System.out.println("错误率:" + String.format("%.2f", errorNums * 100.00 / totalNums));
}

/**
* 实际完成一次请求
*
* @param rea
* @return
* @throws IOException
*/
private RequestResult req(URL rea) throws IOException {
long start = System.currentTimeMillis();
//打开和URL之间的连接
HttpURLConnection connection = (HttpURLConnection) rea.openConnection();
//设置请求属性
connection.setRequestMethod("GET");
// 设置是否使用缓存
connection.setUseCaches(false);
connection.connect();//建立实际的连接
int code = connection.getResponseCode();
long end = System.currentTimeMillis();

return new RequestResult(code, end - start);

}

/**
* 请求结果
*/
public class RequestResult {
int code;
long elapsedTime;

RequestResult(int code, long elapsedTime) {
this.code = code;
this.
elapsedTime = elapsedTime;
}
}
}




用户头像

韩挺

关注

还未添加个人签名 2019.01.25 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营 - 第七周 - 作业