写点什么

第七周命题作业

用户头像
cc
关注
发布于: 2021 年 01 月 10 日

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

【总体趋势】


随着并发的数据增加的时候,刚开始响应的速度都是很快的,随着并发数增加的时候,响应时间就会变长,继续增加会造成应用服务器无响应、奔溃。

【原因分析】

在机器资源一定的时候,随着并发请求不断增加,资源就会发生争抢,集中体现在以下两方面:

1.cpu 的调度需要资源,线程上下文切换频繁需要时间

2.IO 密集型程序,文件的输入输出也非常消耗资源。

当并发量增大,请求处理不过来,就会出现资源被大量的线程占用无法释放,而后续的请求又等待处理,造成了服务器快到慢到奔溃的现象。


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

1.主要定义了两个类:

HttpTest 类:继承 Runnable 接口,实现了 HTTP 访问 URL,记录每次线程访问的响应时间。

ConcurrentTestUtil 类:压测工具类,定义了压测方法的入口,使用了 newFixedThreadPool 来固定控制线程并发数,CountDownLatch 来确保子线程任务跑完,并通知主线程进行平均响应时间等汇总工作。

主要代码如下:

package com.gaoyong.jiagou.yache;
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.net.HttpURLConnection;import java.net.URL;import java.util.List;import java.util.concurrent.CountDownLatch;
/** * 访问URL请求测试类 */public class HtttpTest implements Runnable{ private CountDownLatch countDownLatch; //用来控制并发 private String urlStr; //要访问的URL private List<Long> intervallimes; //响应间隔时间List


@Override public void run() { getHttpResponTime(urlStr); //具体压测代码 countDownLatch.countDown();//当前线程调用此方法,计数器减1 }
public HtttpTest(CountDownLatch countDownLatch, String urlStr, List<Long> intervallimes) { this.countDownLatch = countDownLatch; this.urlStr = urlStr; this.intervallimes = intervallimes; }/** * 计算每次http访问URL的时间 */ public void getHttpResponTime(String urlStr){ long startTime =0; //开始时间 long endTime =0; //结束时间 long intervallime =0; //间隔时间 HttpURLConnection urlConnection = null; InputStream openStream = null; try { startTime = System.currentTimeMillis(); URL url = new URL(urlStr); urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.connect(); openStream = url.openStream(); StringBuilder builder = new StringBuilder(); BufferedReader reader = new BufferedReader(new InputStreamReader(openStream)); String tmp = null; while ((tmp = reader.readLine()) != null) { builder.append(tmp + "\n"); } endTime = System.currentTimeMillis(); intervallime = endTime-startTime; System.out.println("currentThreadName:"+Thread.currentThread().getName()+",耗时:"+intervallime); intervallimes.add(intervallime); } catch (Exception e) { e.printStackTrace(); } finally { if (urlConnection != null) { try { urlConnection.disconnect(); } catch (Exception e) { e.printStackTrace(); } } if (openStream != null) { try { openStream.close(); } catch (IOException e) { e.printStackTrace(); } } }
}}
复制代码


package com.gaoyong.jiagou.yache;
import java.util.ArrayList;import java.util.Collections;import java.util.List;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;
/** * 压测工具类 */
public class ConcurrentTestUtil { /** * 压测方法 * @param urlStr 网址 * @param reqNum 请求次数 * @param concurrNum 并发数 */ public static void doReauest(String urlStr,int reqNum,int concurrNum){ //创建含固定线程数的线程池 ExecutorService executor= Executors.newFixedThreadPool(concurrNum); //初始化计时器 CountDownLatch countDownLatch = new CountDownLatch(reqNum); //间隔时间List List<Long> intervallimes = new ArrayList<Long>(); //开始时间 long startTime = System.currentTimeMillis(); //发起请求 for(int i=0;i<reqNum;i++){ executor.execute(new HtttpTest(countDownLatch,urlStr,intervallimes)); } try { countDownLatch.await(); //阻塞当前线程直到计数器为0 //总响应时间 long totalTime = System.currentTimeMillis() -startTime; //关闭线程池 executor.shutdown(); //对数据进行排序 Collections.sort(intervallimes); System.out.println("intervallimes"+intervallimes); //打印结果 System.out.println("网址: " + urlStr); System.out.println("请求总次数: " + reqNum); System.out.println("并发线程数: " + concurrNum); System.out.println("总响应时间(毫秒): " + totalTime); System.out.println("平均响应时间(毫秒): " + ((double) totalTime / reqNum)); System.out.println("95%时间(毫秒): " + intervallimes.get(95 * reqNum / 100)); System.out.println("---------------------------"); } catch (InterruptedException e) { e.printStackTrace(); } } //测试入口 public static void main(String[] args) { ConcurrentTestUtil.doReauest("https://www.baidu.com",100,10); }}
复制代码

2.执行结果如下图:


用户头像

cc

关注

还未添加个人签名 2018.03.19 加入

还未添加个人简介

评论

发布
暂无评论
第七周命题作业