Week 07 命题作业

用户头像
Jeremy
关注
发布于: 2020 年 07 月 23 日
Week 07 命题作业

作业一

性能压测的时候,随着并发压力的增加,系统响应时间和吞吐量如何变化,为什么?





性能测试的指标:

1、应用系统的负载能力:即系统所能容忍的最大用户数量,也就是在正常的响应时间中,系统能够支持的最多的客户端的数量。

2、应用系统的吞吐率:即应用系统在单位时间内完成的交易量,也就是在单位时间内,应用系统针对不同的负载压力,所能完成的交易数量。

3 、系统的响应能力:即在各种负载压力情况下,系统的响应时间,也就是从客户端请求发起,到服务器端应答返回所需要的时间,包括网络传输时间和服务器处理时间。

4、应用系统的可靠性:即在连续工作时间状态下,系统能够正常运行的时间,即在连续工作时间段内没有出错信息。

一个系统吞吐量通常由 TPS、并发数两个因素决定,每套系统这两个值都有一个相对极限值,在应用场景访问压力下,只要某一项达到系统最高值,系统的吞吐量就上不去了,如果压力继续增大,系统的吞吐量反而会下降。

  1. 假设并发数不变:TPS不断增加,TPS超过最大吞吐量后,会有大量请求等待,平均响应时间急剧下降

  2. 假设 TPS 不变: 增加并发数,会导致CPU并发线程过多,线上上下文切换频繁,内存消耗增加,从而使平均响应时间下降

作业二

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

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;
}
}
}



用户头像

Jeremy

关注

还未添加个人签名 2018.01.21 加入

还未添加个人简介

评论 (1 条评论)

发布
用户头像
作业请加“极客大学架构师训练营”标签,便于分类
2020 年 07 月 27 日 17:13
回复
没有更多了
Week 07 命题作业