架构师训练营 1 期第 7 周:性能优化(一)- 作业
发布于: 2020 年 11 月 07 日
一、性能压测的时候,随着并发压力的增加,系统响应时间和吞吐量如何变化,为什么?
随着并发数的增加,系统吞吐量 TPS 和响应时间变化如下图
上图展示了随着并发数的增加,系统资源的消耗从增加到耗尽的过程。
一开始随着并发数的增加 TPS 近似线性的增加,过了 b 点以后,TPS 的增加开始变缓了,到了 c 点 TPS 达到最大值,然后进一步增加并发请求数,TPS 反而下降了,只至 d 点系统失去响应,TPS 突降为 0。
一开始没有并发请求的时候,服务器资源时空闲的,TPS 为 0,随着并发的增加,服务器会创建线程来处理每个方法请求,每个线程可以获得 CPU 调度,且有足够的内存空间供它使用,访问磁盘访问网络资源都是够用的,所以 TPS 快速的被处理完了,并发数增加资源还都是够用的,TPS 也在快速增加;但是过了某个点 b,资源可能就不足了,就会存在处理线程等待资源的情况,等待的线程没有得到处理,响应时间就会变长,TPS 增加的速度就慢了,但是它还是在增加;到了某个点 c,某些系统资源已经消耗到了极限了,并发数再增加,处理能力反而会下降,比如内存耗尽,需要使用硬盘虚拟内存,CPU 会消耗在虚拟内存置换,唤醒线程的反复切换过程中,处理能力会大幅下降,TPS 也对应减少;到了最后 d 点,到了最后 CPU 什么也处理不了了,一堆线程都在等待资源,资源被耗尽了,所有的请求都失去了响应,系统看起来就崩溃了。
二、 用你熟悉的编程语言写一个 Web 性能压测工具,输入参数:URL,请求总次数,并发数。输出参数:平均响应时间,95%响应时间。用这个测试工具以 10 并发、100 次请求压测 www.baidu.com。
测试代码:
package com.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class PerformanceTest {
public static List<TestResult> results = new ArrayList<>();
private static ReadWriteLock lock = new ReentrantReadWriteLock();
private static Lock writeLock = lock.writeLock();
private static Lock readLock = lock.readLock();
private static final int CONCURRENT_COUNT = 10;
private static final int GROUP_COUNT = 10;
private static final String TEST_URL = "http://www.baidu.com";
public static void addTestResult(TestResult result) {
writeLock.lock();
try {
results.add(result);
} finally {
writeLock.unlock();
}
}
public static int getTestResultCount() {
readLock.lock();
try {
return results.size();
} finally {
readLock.unlock();
}
}
public static void printTestResult() {
readLock.lock();
try {
for (TestResult result: results) {
System.out.println(result.toString());
}
} finally {
readLock.unlock();
}
}
public static long getAverageTime() {
readLock.lock();
try {
long avg = 0,sum = 0;
for (TestResult result: results) {
sum += result.getTime();
}
avg = sum/results.size();
return avg;
} finally {
readLock.unlock();
}
}
public static long get95Time() {
readLock.lock();
try {
Collections.sort(results);
int index = results.size() * 95 / 100;
return results.get(index-1).getTime();
} finally {
readLock.unlock();
}
}
public static void testHttpURlConnection(String urlString){
HttpURLConnection conn = null;
URL url = null;
String result = "";
try {
url = new URL(urlString);
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(10000);
conn.connect();
InputStream urlStream = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(urlStream));
String s = "";
while ((s = reader.readLine()) != null) {
result += s;
}
//System.out.println(result);
reader.close();
urlStream.close();
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch(Exception e){
e.printStackTrace();
}
}
public static class TestResult implements Comparable<TestResult> {
private String url;
private String group;
private long time;
public TestResult(String url, String group, long time) {
this.url = url;
this.group = group;
this.time = time;
}
public String getUrl() {
return url;
}
public String getGroup() {
return group;
}
public long getTime() {
return time;
}
@Override
public int compareTo(TestResult result) {
return ((this.getTime() < result.getTime()) ? (-1)
: ((this.getTime() == result.getTime())
? 0 : 1));
}
@Override
public String toString() {
return " Url: " + this.url + ", Group: " + this.group + ", time:" + this.time;
}
}
public static void main(String[] args) throws Exception {
for (int j = 0; j < GROUP_COUNT; j++) {
int groupCount = getTestResultCount() + CONCURRENT_COUNT;
for (int i = 0; i < CONCURRENT_COUNT; i++) {
String group = "Group" + (j+1);
Thread thread = new Thread(() -> {
long start = System.currentTimeMillis();
testHttpURlConnection(TEST_URL);
long end = System.currentTimeMillis();
TestResult result = new TestResult(TEST_URL, group, end - start);
System.out.println(result.toString());
addTestResult(result);
});
thread.start();
}
while (getTestResultCount() < groupCount) {
Thread.yield();
}
}
System.out.println("平均响应时间:"+ getAverageTime());
System.out.println("95%响应时间:"+ get95Time());
printTestResult();
}
}
复制代码
测试结果:
10并发,100个请求,分10组发送
平均响应时间:13
95%响应时间:48
Url: http://www.baidu.com, Group: Group1, time:47
Url: http://www.baidu.com, Group: Group1, time:46
Url: http://www.baidu.com, Group: Group1, time:47
Url: http://www.baidu.com, Group: Group1, time:46
Url: http://www.baidu.com, Group: Group1, time:48
Url: http://www.baidu.com, Group: Group1, time:49
Url: http://www.baidu.com, Group: Group1, time:48
Url: http://www.baidu.com, Group: Group1, time:49
Url: http://www.baidu.com, Group: Group1, time:49
Url: http://www.baidu.com, Group: Group1, time:49
Url: http://www.baidu.com, Group: Group2, time:6
Url: http://www.baidu.com, Group: Group2, time:7
Url: http://www.baidu.com, Group: Group2, time:7
Url: http://www.baidu.com, Group: Group2, time:7
Url: http://www.baidu.com, Group: Group2, time:7
Url: http://www.baidu.com, Group: Group2, time:14
Url: http://www.baidu.com, Group: Group2, time:14
Url: http://www.baidu.com, Group: Group2, time:13
Url: http://www.baidu.com, Group: Group2, time:14
Url: http://www.baidu.com, Group: Group2, time:15
Url: http://www.baidu.com, Group: Group3, time:7
Url: http://www.baidu.com, Group: Group3, time:7
Url: http://www.baidu.com, Group: Group3, time:7
Url: http://www.baidu.com, Group: Group3, time:7
Url: http://www.baidu.com, Group: Group3, time:7
Url: http://www.baidu.com, Group: Group3, time:13
Url: http://www.baidu.com, Group: Group3, time:14
Url: http://www.baidu.com, Group: Group3, time:14
Url: http://www.baidu.com, Group: Group3, time:15
Url: http://www.baidu.com, Group: Group3, time:14
Url: http://www.baidu.com, Group: Group4, time:7
Url: http://www.baidu.com, Group: Group4, time:7
Url: http://www.baidu.com, Group: Group4, time:7
Url: http://www.baidu.com, Group: Group4, time:6
Url: http://www.baidu.com, Group: Group4, time:6
Url: http://www.baidu.com, Group: Group4, time:13
Url: http://www.baidu.com, Group: Group4, time:13
Url: http://www.baidu.com, Group: Group4, time:13
Url: http://www.baidu.com, Group: Group4, time:14
Url: http://www.baidu.com, Group: Group4, time:14
Url: http://www.baidu.com, Group: Group5, time:6
Url: http://www.baidu.com, Group: Group5, time:6
Url: http://www.baidu.com, Group: Group5, time:8
Url: http://www.baidu.com, Group: Group5, time:7
Url: http://www.baidu.com, Group: Group5, time:7
Url: http://www.baidu.com, Group: Group5, time:12
Url: http://www.baidu.com, Group: Group5, time:9
Url: http://www.baidu.com, Group: Group5, time:13
Url: http://www.baidu.com, Group: Group5, time:12
Url: http://www.baidu.com, Group: Group5, time:17
Url: http://www.baidu.com, Group: Group6, time:6
Url: http://www.baidu.com, Group: Group6, time:6
Url: http://www.baidu.com, Group: Group6, time:7
Url: http://www.baidu.com, Group: Group6, time:7
Url: http://www.baidu.com, Group: Group6, time:7
Url: http://www.baidu.com, Group: Group6, time:12
Url: http://www.baidu.com, Group: Group6, time:11
Url: http://www.baidu.com, Group: Group6, time:12
Url: http://www.baidu.com, Group: Group6, time:12
Url: http://www.baidu.com, Group: Group6, time:21
Url: http://www.baidu.com, Group: Group7, time:6
Url: http://www.baidu.com, Group: Group7, time:6
Url: http://www.baidu.com, Group: Group7, time:6
Url: http://www.baidu.com, Group: Group7, time:7
Url: http://www.baidu.com, Group: Group7, time:7
Url: http://www.baidu.com, Group: Group7, time:12
Url: http://www.baidu.com, Group: Group7, time:12
Url: http://www.baidu.com, Group: Group7, time:12
Url: http://www.baidu.com, Group: Group7, time:14
Url: http://www.baidu.com, Group: Group7, time:15
Url: http://www.baidu.com, Group: Group8, time:8
Url: http://www.baidu.com, Group: Group8, time:8
Url: http://www.baidu.com, Group: Group8, time:8
Url: http://www.baidu.com, Group: Group8, time:8
Url: http://www.baidu.com, Group: Group8, time:8
Url: http://www.baidu.com, Group: Group8, time:14
Url: http://www.baidu.com, Group: Group8, time:13
Url: http://www.baidu.com, Group: Group8, time:14
Url: http://www.baidu.com, Group: Group8, time:15
Url: http://www.baidu.com, Group: Group8, time:21
Url: http://www.baidu.com, Group: Group9, time:7
Url: http://www.baidu.com, Group: Group9, time:7
Url: http://www.baidu.com, Group: Group9, time:7
Url: http://www.baidu.com, Group: Group9, time:7
Url: http://www.baidu.com, Group: Group9, time:7
Url: http://www.baidu.com, Group: Group9, time:13
Url: http://www.baidu.com, Group: Group9, time:13
Url: http://www.baidu.com, Group: Group9, time:13
Url: http://www.baidu.com, Group: Group9, time:13
Url: http://www.baidu.com, Group: Group9, time:13
Url: http://www.baidu.com, Group: Group10, time:7
Url: http://www.baidu.com, Group: Group10, time:7
Url: http://www.baidu.com, Group: Group10, time:6
Url: http://www.baidu.com, Group: Group10, time:7
Url: http://www.baidu.com, Group: Group10, time:7
Url: http://www.baidu.com, Group: Group10, time:12
Url: http://www.baidu.com, Group: Group10, time:12
Url: http://www.baidu.com, Group: Group10, time:12
Url: http://www.baidu.com, Group: Group10, time:12
Url: http://www.baidu.com, Group: Group10, time:12
复制代码
划线
评论
复制
发布于: 2020 年 11 月 07 日阅读数: 35
版权声明: 本文为 InfoQ 作者【piercebn】的原创文章。
原文链接:【http://xie.infoq.cn/article/385b534ea0fd7100e8ffc7329】。文章转载请联系作者。
piercebn
关注
还未添加个人签名 2019.07.24 加入
还未添加个人简介
评论