写点什么

Week7 作业

用户头像
TiK
关注
发布于: 2020 年 07 月 22 日

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



吞吐量(TPS)=(1000/响应时间ms)*并发数





随着并发压力的增加,吞吐量会先有一个迅速增加的过程,响应时间比较平稳。此时系统的资源逐渐开始被利用起来;当继续增大并发量,TPS增加幅度会减少,逐渐达到最大值。响应时间会略有增加,达到系统的最大负荷点;继续加压,会出现系统资源不够用的情况,用户请求出现排队现象,响应时间会变得很长,从而影响吞吐量;最终响服务器资源耗尽,响应时间无限长,没有吞吐量。



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



思路:将多次请求分成多个子任务,由多个线程处理。最后对测试结果进行汇总分析。jdk8以上可以用并行流简化处理。jdk7可直接使用ForkJoinPoll.







实现代码:

LoadTestTask

package camp.week7;
import lombok.extern.slf4j.Slf4j;
import sun.net.www.http.HttpClient;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.RecursiveTask;
@Slf4j
public class LoadTestTask extends RecursiveTask<List<ExecutionResult>> {
private final long[] sampleNumbers;
private final int start;
private final int end;
private int concurrentNumber = 10;
private String url;
private LoadTestTask(long[] sampleNumbers, int start, int end, int concurrentNumber, String url) {
super();
this.sampleNumbers = sampleNumbers;
this.start = start;
this.end = end;
this.concurrentNumber = concurrentNumber;
this.url = url;
}
public LoadTestTask(long[] sampleNumbers, int concurrentNumber, String url) {
super();
this.sampleNumbers = sampleNumbers;
this.start = 0;
this.end = sampleNumbers.length;
this.concurrentNumber = concurrentNumber;
this.url = url;
}
@Override
protected List<ExecutionResult> compute() {
int length = end - start;
if (length <= sampleNumbers.length / concurrentNumber) {
try {
return computeSequentially();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
LoadTestTask leftTask = new LoadTestTask(sampleNumbers, start, start + length / 2, concurrentNumber, url);
leftTask.fork();
LoadTestTask rightTask = new LoadTestTask(sampleNumbers, start + length / 2, end, concurrentNumber, url);
rightTask.fork();
List<ExecutionResult> rightResult = null;
try {
rightResult = rightTask.get();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
List<ExecutionResult> leftResult = leftTask.join();
ArrayList<ExecutionResult> results = new ArrayList<>();
results.addAll(leftResult);
results.addAll(rightResult);
return results;
}
private List<ExecutionResult> computeSequentially() throws Exception {
List<ExecutionResult> list = new ArrayList<>();
for (int i = start; i < end; i++) {
long startTime = System.currentTimeMillis();
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestMethod("GET");
connection.connect();
int responseCode = connection.getResponseCode();
String response = null;
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = connection.getInputStream();
response = streamToString(inputStream);
}
long finishTime = System.currentTimeMillis();
ExecutionResult executionResult = ExecutionResult.builder()
.id(sampleNumbers[i])
.threadName(Thread.currentThread().getName())
.startTime(startTime)
.finishTime(finishTime)
.executionTime(finishTime - startTime)
.response(response)
.build();
list.add(executionResult);
}
return list;
}
private String streamToString(InputStream is) {
String result = "";
try {
byte[] bytes = new byte[0];
bytes = new byte[is.available()];
is.read(bytes);
result = new String(bytes);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return result;
}
}

AggregationAnalyzer

package camp.week7;
import java.util.Comparator;
import java.util.List;
import java.util.OptionalDouble;
import java.util.stream.Collectors;
public class AggregationAnalyzer {
public static AggregationReport analyze(List<ExecutionResult> results) {
List<ExecutionResult> sortedResult = results.stream()
.sorted(Comparator.comparing(ExecutionResult::getExecutionTime))
.collect(Collectors.toList());
double avg = sortedResult.stream().mapToLong(ExecutionResult::getExecutionTime).average().orElse(0d);
int ninetyFive = (int) (sortedResult.size() * 0.95);
int fifty = (int) (sortedResult.size() * 0.50);
AggregationReport report = AggregationReport.builder()
.minResTime(sortedResult.get(0).getExecutionTime())
.maxResTime(sortedResult.get(sortedResult.size() - 1).getExecutionTime())
.avgResTime(avg)
.fiftyResTime(sortedResult.get(fifty).getExecutionTime())
.ninetyFiveResTime(sortedResult.get(ninetyFive).getExecutionTime())
.build();
return report;
}
}



ExecutionResult

package camp.week7;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class ExecutionResult {
private Long id;
private Long startTime;
private Long finishTime;
private Long executionTime;
private String threadName;
private String response;
}

AggregationReport

package camp.week7;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class AggregationReport {
private long maxResTime;
private long minResTime;
private double avgResTime;
private long ninetyFiveResTime;
private long fiftyResTime;
public String toString() {
StringBuilder sb = new StringBuilder("Aggregation Report:");
sb.append(" min->").append(this.getMinResTime());
sb.append(" max->").append(this.getMaxResTime());
sb.append(" avg->").append(this.getAvgResTime());
sb.append(" 50%->").append(this.getFiftyResTime());
sb.append(" 95%->").append(this.getNinetyFiveResTime());
return sb.toString();
}
}



LoadTestTool

package camp.week7;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.stream.Collectors;
import java.util.stream.LongStream;
public class LoadTestTool {
public static void main(String[] args) {
long sampleNumber = 100;
int concurrentNumber = 10;
String url = "http://www.baidu.com";
long[] sampleNumbers = LongStream.rangeClosed(1, sampleNumber).toArray();
List<ExecutionResult> results = new ForkJoinPool(concurrentNumber)
.invoke(new LoadTestTask(sampleNumbers, concurrentNumber, url));
AggregationReport report = AggregationAnalyzer.analyze(results);
System.out.println(report);
}
}



结果输出:

Aggregation Report: min->46 max->729 avg->105.52 50%->61 95%->273



用户头像

TiK

关注

还未添加个人签名 2018.04.26 加入

还未添加个人简介

评论

发布
暂无评论
Week7 作业