写点什么

2020-07-18- 第七周作业

发布于: 2020 年 07 月 22 日

作业一


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

答:

随着并发压力的增加,系统的响应时间应该是越来越高。而对应的吞吐量应该在增加到一个临界点后随着并发压力的增加,吞吐量会越来越小。


下图横轴是并发数,纵轴是系统吞吐量,可以看到当并发数在[0,a]性能测试区间时,系统的吞吐量是 0。在[a-b]区间随着并发数的增加,系统吞吐量也随之增加,这一段接近于线性增长。在[b-c]负载测试区间继续增加并发数,系统吞吐量也在增加,但是增长很慢。到了 c 点,便是系统最大吞吐量。在[c-d]压力测试区间继续增加并发数,会使系统吞吐量骤减,这是因为并发请求越多,消耗的系统资源也就越多,线程不断争夺资源,而此时的并发请求数已经达到系统的极限,系统处理不了这么多的请求,响应时间变得越来越长,对应的系统吞吐量也就越来越小了。直到到达 d 点后,系统进入崩溃状态。



作业二


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

答:

输入参数:请求地址、请求总次数、并发数

static String url = "https://www.baidu.com";static int count = 100;	// 请求总次数static int batchSize = 10;	// 并发数
复制代码


开始测试,循环 100 次,每次并发 10 个线程请求,同时记录每次总响应时间。


int index = 0;	// 请求次数long[] responseTimeArr = new long[count];	// 响应时间数组while(index < count) {	// 循环100次    // 使用线程池,固定10个线程    ExecutorService executorService = Executors.newFixedThreadPool(batchSize);	    long t1 = System.currentTimeMillis();	// 开始时间    for(int i = 0; i < batchSize; i++) {        executorService.submit(new Runnable() {            @Override            public void run() {                getRequest(url);	// 请求url            }        });    }    executorService.shutdown();    while(!executorService.isTerminated()) {        // 等待线程池关闭    }    long t2 = System.currentTimeMillis();	// 结束时间    System.out.println(String.format("第%s批总耗时:%sms", index, (t2-t1)));    responseTimeArr[index++] = t2 - t1;}
复制代码

HTTP 使用 GET 方法进行请求

public static String getRequest(String requestUrl){    HttpURLConnection connection = null;    InputStream is = null;    BufferedReader br = null;    String result = null;// 返回结果字符串    try {        // 创建远程url连接对象        URL url = new URL(requestUrl);        // 通过远程url连接对象打开一个连接,强转成httpURLConnection类        connection = (HttpURLConnection) url.openConnection();        // 设置连接方式:get        connection.setRequestMethod("GET");        // 设置连接主机服务器的超时时间:15000毫秒        connection.setConnectTimeout(15000);        // 设置读取远程返回的数据时间:60000毫秒        connection.setReadTimeout(60000);        // 发送请求        connection.connect();        // 通过connection连接,获取输入流        if (connection.getResponseCode() == 200) {            is = connection.getInputStream();            // 封装输入流is,并指定字符集            br = new BufferedReader(new InputStreamReader(is, "UTF-8"));            // 存放数据            StringBuffer sbf = new StringBuffer();            String temp = null;            while ((temp = br.readLine()) != null) {                sbf.append(temp);                sbf.append("\r\n");            }            result = sbf.toString();        }    } catch (Exception e) {        e.printStackTrace();    } finally {        // 关闭资源        if (null != br) {            try {                br.close();            } catch (IOException e) {                e.printStackTrace();            }        }
if (null != is) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } }
connection.disconnect();// 关闭远程连接 } return result;}
复制代码

计算响应时间和 95%响应时间

// 计算平均耗时long[] resTop6 = new long[6];       // 倒序存储最大的6个响应时间long sum = 0;for(int i = 0; i < responseTimeArr.length; i++) {    long cur = responseTimeArr[i];    for(int j = 0; j < resTop6.length; j++) {        if(resTop6[j] < cur) {            for(int k = resTop6.length - 1; k > j; k--) {                resTop6[k] = resTop6[k-1];            }            resTop6[j] = cur;            break;        }    }    sum += cur;}long avg = sum / responseTimeArr.length;	// 计算平均响应时间long res95 = resTop6[resTop6.length - 1];	// 95%响应时间for(int i = 0; i < resTop6.length; i++) {    System.out.print(resTop6[i] + ", ");}System.out.println();System.out.println(String.format("平均响应时间:%sms,95响应时间:%sms", avg, res95));
复制代码

测试结果

1072, 164, 151, 107, 54, 52,	// 响应时间最大的前6个平均响应时间:40ms,95响应时间:52ms
复制代码



用户头像

还未添加个人签名 2020.05.11 加入

还未添加个人简介

评论

发布
暂无评论
2020-07-18-第七周作业