Week 07 命题作业
发布于: 2020 年 07 月 23 日
作业一
性能压测的时候,随着并发压力的增加,系统响应时间和吞吐量如何变化,为什么?
性能测试的指标:
1、应用系统的负载能力:即系统所能容忍的最大用户数量,也就是在正常的响应时间中,系统能够支持的最多的客户端的数量。
2、应用系统的吞吐率:即应用系统在单位时间内完成的交易量,也就是在单位时间内,应用系统针对不同的负载压力,所能完成的交易数量。
3 、系统的响应能力:即在各种负载压力情况下,系统的响应时间,也就是从客户端请求发起,到服务器端应答返回所需要的时间,包括网络传输时间和服务器处理时间。
4、应用系统的可靠性:即在连续工作时间状态下,系统能够正常运行的时间,即在连续工作时间段内没有出错信息。
一个系统吞吐量通常由 TPS、并发数两个因素决定,每套系统这两个值都有一个相对极限值,在应用场景访问压力下,只要某一项达到系统最高值,系统的吞吐量就上不去了,如果压力继续增大,系统的吞吐量反而会下降。
假设并发数不变:TPS不断增加,TPS超过最大吞吐量后,会有大量请求等待,平均响应时间急剧下降
假设 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; } }}
划线
评论
复制
发布于: 2020 年 07 月 23 日阅读数: 50
Jeremy
关注
还未添加个人签名 2018.01.21 加入
还未添加个人简介
评论 (1 条评论)