架构师训练 第七周 作业

用户头像
李君
关注
发布于: 2020 年 07 月 22 日
架构师训练 第七周 作业

作业 1

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

吞吐量





  • 性能测试时随着并发数据的增加,当服务器资源还是比较空闲时吞吐量是不断上升,当网络和服务器资源逐渐到达满载吞吐量会到达一个高峰值。当并发数还在不断的增加服务器处理不过来时,吞吐量会逐渐下降,直至系统崩溃。

响应时间





  • 当服务器资源还比较空闲时响应时间是比较短的,当并发量的不断增加,系统资源不断消耗,新的请求处理不过来,响应时间会逐渐变长。当并发量还在不断的增加是就会导致服务器资源耗尽失去响应。



作业 2.

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

类图



测试Case模板类
/**
* TestCase 模板
*
* @author Lee
* @date 2020/7/21 16:20
*/
public abstract class BaseTestCase implements Callable {
/**
* case 执行抽象方法
*
* @return
*/
public abstract Result execution();
}
测试case
/**
* 测试case类
* @author Lee
*/
public class TestGetRequest extends BaseTestCase {
/**
* 测试用 url
*/
private String url;
public TestGetRequest(String url) {
this.url = url;
}
/**
* 请求执行
*
* @return Result
*/
@Override
public Result execution() {
CloseableHttpClient httpClient = HttpClients.createDefault();
// 创建Get请求
HttpGet httpGet = new HttpGet(this.url);
long t1 = System.currentTimeMillis();
CloseableHttpResponse response = null;
try {
response = httpClient.execute(httpGet);
} catch (IOException e) {
e.printStackTrace();
}
long t2 = 0L;
Result result = new Result();
// 访问成功
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
t2 = System.currentTimeMillis();
result.setResponseTime(t2 -t1);
result.setSuccess(true);
}
// 访问失败
else {
t2 = System.currentTimeMillis();
result.setResponseTime(t2 -t1);
result.setSuccess(false);
}
return result;
}
@Override
public Object call() throws Exception {
return execution();
}
}



测试结果类
/**
* 测试返回结果
*
* @author Lee
* @date 2020/7/21 9:00
*/
public class Result {
/**
* 响应时间
*/
private Long responseTime;
/**
* 访问是否成功
*/
private boolean success;
public Long getResponseTime() {
return responseTime;
}
public void setResponseTime(Long responseTime) {
this.responseTime = responseTime;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
}
测试报告模板
/**
* 测试报告模板
*
* @author rikun
*/
public abstract class BaseTestReport {
/**
* 测试报告生成
*
* @param results
*/
public abstract void calResult(List<Future<Result>> results);
}
测试报告
/**
* 测试报告
*
* @author Lee
* @date 2020/7/21 8:43
*/
public class TestReport extends BaseTestReport {
private int numberOfTests;
public TestReport(int numOfTests) {
this.numberOfTests = numOfTests;
}
/**
* 计算出测试结果
*
* @param results
* @return
*/
@Override
public void calResult(List<Future<Result>> results) {
// 取出每次的请求的响应时间
List<Long> list = new ArrayList<>();
try{
for (Future<Result> item: results) {
Result result = item.get();
list.add(result.getResponseTime());
}
} catch (ExecutionException | InterruptedException ignored) {
ignored.printStackTrace();
}
// 按大小排序
list.sort(Comparator.comparingLong(Long:: longValue));
// 求 95% 响应时间 序号
int ninetyFiveRT = BigDecimal.valueOf(numberOfTests).multiply(BigDecimal.valueOf(0.95D)).setScale(0, BigDecimal.ROUND_UP).intValue();
// 求 平均响应时间
double avgRt = list.stream().mapToLong(Long::longValue).average().getAsDouble();
// 打印出测试结果
System.out.println("平均响应时间: " + BigDecimal.valueOf(avgRt).setScale(0, BigDecimal.ROUND_UP) + ";");
System.out.println("95%响应时间: " + list.get(ninetyFiveRT) + ";");
}
}
测试任务设定类
/**
* 任务设定
*
* @author rikun
*/
public class TaskConfiguration {
/**
* 并发数
*/
private int concurrentNum;
/**
* 批次数
*/
private int numberOfTests;
/**
* 线程池
*/
private ExecutorService pool;
/**
* 测试类型
*/
private BaseTestCase testCase;
/**
* 测试报告
*/
private BaseTestReport testReport;
/**
* 测试计划配置
*
* @param concurrentNum int
* @param numberOfTests int
*/
public TaskConfiguration(int concurrentNum, int numberOfTests) {
this.concurrentNum = concurrentNum;
this.numberOfTests = numberOfTests;
this.pool = new ThreadPoolExecutor(numberOfTests,
numberOfTests,
0,
TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
}
/**
* 设置测试case
*
* @param testCase
*/
public void setTestCase(BaseTestCase testCase) {
this.testCase = testCase;
}
/**
* 设置测试报告
*
* @param testReport
*/
public void setTestReport(BaseTestReport testReport) {
this.testReport = testReport;
}
/**
* 多批次执行
*
* @throws InterruptedException
*/
public void testExecute() throws InterruptedException {
if (this.testCase == null) {
System.out.println("请设定测试case,否则测试无法进行");
return;
}
BigDecimal val1 = BigDecimal.valueOf(concurrentNum);
BigDecimal val2 = BigDecimal.valueOf(numberOfTests);
int result = val2.divide(val1, BigDecimal.ROUND_UP).intValue();
List<Future<Result>> results = new ArrayList<>();
// 将请求分批发送
for (int i = 0; i< result; i++) {
int size = concurrentNum;
if ( i+1 == result) {
size = numberOfTests - (concurrentNum * i);
}
results.addAll(singleExecution(size));
}
// 释放资源
pool.shutdown();
if (this.testReport == null) {
System.out.println("请设定测试报告,否则无法查看测试结果");
}
else {
this.testReport.calResult(results);
}
}
/**
* 单批次执行
*
* @throws InterruptedException
*/
private List<Future<Result>> singleExecution(int size) throws InterruptedException {
List<Callable<Result>> tasks = new ArrayList<>();
for (int i = 0; i< size; i++) {
tasks.add(this.testCase);
}
// 批量执行任务
return pool.invokeAll(tasks);
}
}
测试执行
/**
* 执行测试
*
* @author Lee
*/
public class Client {
public static void main(String[] args) throws ExecutionException, InterruptedException {
int numberOfTests = 100;
// 测试的并发数,请求数 设定
TaskConfiguration taskExecution =
new TaskConfiguration(10,
numberOfTests);
// 设定测试case
taskExecution.setTestCase(new TestGetRequest("http://www.baidu.com"));
// 设定测试报告
taskExecution.setTestReport(new TestReport(numberOfTests));
// 执行测试计划
taskExecution.testExecute();
}
}
测试结果
平均响应时间: 27;
95%响应时间: 67;



发布于: 2020 年 07 月 22 日 阅读数: 20
用户头像

李君

关注

结硬寨,打呆仗。 2018.09.11 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练 第七周 作业