架构师训练营 - 作业 - 第七周

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

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

随着并发压力的增加,系统的响应时间从平稳到逐步上升,当超过负载点后会激增,并最终导致系统崩溃、失去响应。

吞吐量会随着并发数增加,然后趋于平稳,当超过负载点后,吞吐量会下降,并最终导致系统崩溃。

这是由于起初系统在没有达到满负荷的阶段,系统处于一个比较好的稳定的状态,当负载过大后,系统资源(CPU/内存/网络/磁盘等)满负荷运作,会导致大量请求无法及时处理,大量的堆积会耗尽资源,最终导致系统崩溃。

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

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ResponseTimeTest {
private final String url;
private final int requestCount;
private final ExecutorService pool;
private List<Long> responseTimeList;
public ResponseTimeTest(final String url, final int requestCount, final ExecutorService pool) {
this.url = url;
this.requestCount = requestCount;
this.pool = pool;
}
private void run() {
final CountDownLatch doneSignal = new CountDownLatch(requestCount);
final Queue<Long> responseTimeQueue = new ConcurrentLinkedDeque<>();
for (int i = 0; i < requestCount; i++) {
pool.execute(new Runnable() {
@Override
public void run() {
HttpURLConnection urlConnection = null;
final long startTime = System.currentTimeMillis();
try {
final URL link = new URL(url);
urlConnection = (HttpURLConnection) link.openConnection();
urlConnection.setRequestMethod("GET");
InputStream response = urlConnection.getInputStream();
response.close();
} catch (final Exception e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
final long endTime = System.currentTimeMillis();
responseTimeQueue.add(endTime - startTime);
doneSignal.countDown();
}
});
}
try {
doneSignal.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
responseTimeList = new ArrayList<>(responseTimeQueue);
}
private long getAvgResponseTime() {
long total = 0;
for (Long responseTime : responseTimeList) {
total += responseTime;
}
return total / responseTimeList.size();
}
private long get95PercentResponseTime() {
responseTimeList.sort(Long::compareTo);
int index = (int) Math.ceil(95 / 100.0 * responseTimeList.size());
return responseTimeList.get(index-1);
}
public static void main(final String[] args) {
final String URL = "https://baidu.com";
final int CONCURRENT_COUNT = 10;
final int REQUEST_COUNT = 100;
final ExecutorService pool = Executors.newFixedThreadPool(CONCURRENT_COUNT);
final ResponseTimeTest responseTimeTest = new ResponseTimeTest(URL, REQUEST_COUNT, pool);
responseTimeTest.run();
System.out.println("Concurrent Count: " + CONCURRENT_COUNT);
System.out.println("Request Count: " + REQUEST_COUNT);
System.out.println("Average Response Time: " + responseTimeTest.getAvgResponseTime() + " ms");
System.out.println("95% Response Time: " + responseTimeTest.get95PercentResponseTime() + " ms");
pool.shutdown();
}
}



Reference

https://xie.infoq.cn/article/2af15d3db0b6db8e4ecd6d416

https://xie.infoq.cn/article/cf1a3b532daab4bf52085e941

https://xie.infoq.cn/article/1da4db40e7d6aa9835b336edf

https://xie.infoq.cn/article/5d40a17dbcd11e0f29201749f



用户头像

心在飞

关注

还未添加个人签名 2017.10.15 加入

2个女儿的爸爸 | 程序员 | CS 反恐精英

评论 (2 条评论)

发布
用户头像
是本机跑的,不是服务的数据是么?95分值跟我一样,其他大部分同学都和均值相仿。
2020 年 07 月 25 日 17:02
回复
我是本机跑的,我家电信100MB带宽。
2020 年 07 月 26 日 09:01
回复
没有更多了
架构师训练营 - 作业 - 第七周