第七周命题作业
发布于: 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.执行结果如下图:
划线
评论
复制
发布于: 2021 年 01 月 10 日阅读数: 17
cc
关注
还未添加个人签名 2018.03.19 加入
还未添加个人简介
评论