架构师训练营 week7 作业
发布于: 2020 年 07 月 22 日
1、性能压测的时候,随着并发压力的增加,系统响应时间和吞吐量如何变化,为什么?
当并发压力达到系统负载最优点前,系统响应时间与吞吐量都是增加的。但是当超过最优点时,系统响应时间成指数级上升,而吞吐量却下降。这是因为,系统资源是有限的,随着并发数的增加,CPU的使用随之增加,但是一个系统是存在性能瓶颈的,达到这个瓶颈,并发数继续上升反而对系统不利,CPU来不及处理请求,导致响应时间指数级增加,吞吐量急剧下降,最终系统会崩溃。
2、用你熟悉的编程语言写一个 web 性能压测工具,输入参数:URL,请求总次数,并发数。输出参数:平均响应时间,95% 响应时间。用这个测试工具以 10 并发、100 次请求压测 www.baidu.com。
代码实参考助教实现:
需要一个线程池来伪造并发请求。
package com.jacky.jikertime.architectlesson.benchmark;import com.google.common.collect.Lists;import okhttp3.Call;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.Response;import org.apache.commons.lang3.RandomUtils;import java.util.Comparator;import java.util.List;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;public class BenchMarkUtil { //测试方法 public static String testAb(int reqs, int concurrents, String testUrl) throws InterruptedException, ExecutionException { //新建一个线程池 ExecutorService executor = Executors.newFixedThreadPool(concurrents); List<Callable<Long>> callableList = Lists.newArrayList(); //构造reqs个请求 for (int i = 0; i < reqs; i++) { callableList.add(new ABTask(testUrl)); } //执行请求 List<Future<Long>> futureList = executor.invokeAll(callableList); List<Long> executeTimeList = Lists.newArrayList(); Long totalTime = 0L; for (Future<Long> longFuture : futureList) { Long time = longFuture.get(); executeTimeList.add(time); totalTime += time; } executeTimeList.sort(Comparator.naturalOrder()); long ninetyfiveindex = Math.round(reqs * 0.95); String inputInfo= String.format("输入参数URL:%s 请求总次数 %s 并发数%s \n",testUrl,reqs,concurrents); String ninetyfiveResult = "95% 响应时间: " + executeTimeList.get((int) ninetyfiveindex) + "毫秒\n"; String averageTime = "平均响应时间" + totalTime / reqs+"毫秒"; executor.shutdown(); return inputInfo+ninetyfiveResult+averageTime; } //请求类实现线程接口 public static class ABTask implements Callable<Long> { private String testUrl; public ABTask(String testUrl) { this.testUrl = testUrl; } //重写方法 @Override public Long call() throws Exception { OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder().url(testUrl).get() .build(); long start = System.currentTimeMillis(); final Call call = client.newCall(request); Response response = call.execute(); if (response.isSuccessful()) { long end = System.currentTimeMillis(); long usedTime = end - start; System.out.println("calling " + testUrl + " used:" + usedTime); return usedTime; } else { throw new RuntimeException("call failed"); } } } //执行测试 public static void main(String[] args) { try { System.out.println(testAb(100, 10, "http://www.baidu.com")); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }}
划线
评论
复制
发布于: 2020 年 07 月 22 日 阅读数: 28
Up
关注
代码,思考,架构,阅读,旅行。 2018.11.02 加入
一起来进步吧,持续学习的小白!
评论