写点什么

架构师训练营 1 期第 7 周:性能优化(一)- 作业

用户头像
piercebn
关注
发布于: 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组发送平均响应时间:1395%响应时间: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
用户头像

piercebn

关注

还未添加个人签名 2019.07.24 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营 1 期第 7 周:性能优化(一)- 作业