架构师训练营第七周作业

用户头像
文智
关注
发布于: 2020 年 11 月 09 日

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

  • 随着并发压力增加,系统响应时间会逐渐增大,压力到达一定阈值后,响应时间会急剧增加,直至系统崩溃

  • 随着并发压力增加,吞吐量首先会逐渐增加,增加幅度会逐渐放缓,压力到达一定阈值后吞吐量会逐渐减小,幅度会越来越大,直至系统崩溃

  • 导致以上变化的原因为:

  • 并发数较小时,系统资源足够,系统收到请求后无需等待或等待时间较短,所以响应时间变化不大,而吞吐量 = (1000 / 响应时间ms) x 并发数,所以吞吐量随并发数增加而增加;

  • 并发数较大时,系统资源不足以分配给每个请求,CPU需要调度系统资源,如在内存耗尽的情况下使用虚拟内存,虚拟内存的读写速度远低于内存的读写速度,响应时间相应变长,另一方面,线程之间切换也有时间开销,因此吞吐量会逐渐减小



性能压测工具

  • 开发语言为Java,使用CloseableHttpClient完成请求

package com.colin.benchmarker;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.http.ConnectionReuseStrategy;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HttpContext;
public class CustomBenchMarker {
/**
* 返回时间
*/
List<Long> responseTimes;
/**
* 测试地址
*/
String url;
/**
* 并发数
*/
int concurrency;
/**
* 总请求次数
*/
AtomicInteger totalRequests;
CloseableHttpClient httpClient;
HttpGet httpGet;
ExecutorService executorService;
public CustomBenchMarker(String url, int concurrency, int total) {
this.url = url;
this.concurrency = concurrency;
totalRequests = new AtomicInteger(total);
List<Long> list = new LinkedList<Long>();
this.responseTimes = Collections.synchronizedList(list);
executorService = Executors.newFixedThreadPool(concurrency);
httpClient = HttpClients.custom().setMaxConnPerRoute(concurrency)
.setConnectionReuseStrategy(new ConnectionReuseStrategy() {
@Override
public boolean keepAlive(HttpResponse response, HttpContext context) {
return true;
}
}).build();
httpGet = new HttpGet(url);
}
public void startTest() throws Exception {
for (int i = 0; i < concurrency; ++i) {
executorService.execute(() -> {
try {
test();
} catch (Exception e) {
e.printStackTrace();
}
});
}
executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println(responseTimes.size());
}
public void report() {
int requestCounts = responseTimes.size();
responseTimes.sort((a, b) -> a.compareTo(b));
Long p50 = responseTimes.get((int) (requestCounts * 0.5));
Long p95 = responseTimes.get((int) (requestCounts * 0.95));
Long p99 = responseTimes.get((int) (requestCounts * 0.99));
long avgResponseTime = 0;
for (int i = 0; i < requestCounts; ++i) {
avgResponseTime += responseTimes.get(i);
}
System.out.println(String.format("average response time: %d", avgResponseTime / requestCounts));
System.out.println(String.format("50%% response time: %d", p50));
System.out.println(String.format("95%% response time: %d", p95));
System.out.println(String.format("99%% response time: %d", p99));
}
public void test() throws Exception {
Long responseTime = 0l;
Long taskStart;
while (totalRequests.decrementAndGet() > 0) {
taskStart = System.currentTimeMillis();
CloseableHttpResponse response = httpClient.execute(httpGet);
response.close();
responseTime = System.currentTimeMillis() - taskStart;
responseTimes.add(responseTime);
}
}
public static void main(String[] args) throws Exception {
CustomBenchMarker benchMarker = new CustomBenchMarker("https://www.baidu.com", 10, 100);
benchMarker.startTest();
benchMarker.report();
}
}
  • 输出示例:

average response time: 57
50% response time: 44
95% response time: 183
99% response time: 184



发布于: 2020 年 11 月 09 日阅读数: 30
用户头像

文智

关注

还未添加个人签名 2018.11.29 加入

还未添加个人简介

评论

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