写点什么

架构师训练营 -week7- 作业

发布于: 2020 年 07 月 22 日
架构师训练营-week7-作业
  1. 性能压测的时候,随着并发压力的增加,系统响应时间和吞吐量如何变化,为什么?

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

在性能压测的性能测试阶段,可根据公式可得出,当并发数增加,平均响应时间不变时,此时系统资源充足,吞吐量随着并发数增加而增加。

当并发数达到某个点时,进入负载测试阶段,当并发数增加,平均响应时间不变时,此时系统资源比较紧张,接近极限,吞吐量不再随着并发数线性增加,而是缓慢增加。

当吞吐量达到曲线峰值时,则进入压力测试阶段,此时并发数增加,此时系统资源被耗尽,平均响应时间增加,吞吐量随着并发数的增大而减小。


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

PerformanceBox

package week7;
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.util.Collections;import java.util.Vector;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;
public class PerformenceBox { private int parCount; private int requestTotalCount; private String requestUrl; private CyclicBarrier cyclicBarrier; private ExecutorService pool; private Vector<Long> cost; private int currentThreadCount;
public PerformenceBox(int parCount, int requestTotalCount, String Url) { this.parCount = parCount; this.requestTotalCount = requestTotalCount; this.requestUrl = Url; this.currentThreadCount = parCount; this.cost = new Vector<>(); this.pool = Executors.newFixedThreadPool(this.parCount); this.cyclicBarrier = new CyclicBarrier(this.parCount); }
public void Execute() throws InterruptedException { // 开始执行 for (int i = 0; i < this.parCount; i++) { pool.submit(new Task(cyclicBarrier, this.requestTotalCount / this.parCount)); }
do { Thread.sleep(1000); } while (currentThreadCount > 0);
pool.shutdown(); }
public String outputPerformance() { //从小到大排序,方便计算95%响应时间 Collections.sort(cost, (o1, o2) -> o1.compareTo(o2)); int percentile95Indx = (int) Math.ceil(cost.size() * 0.95); double total = 0; for (int i = 0; i < cost.size(); i++) { total += cost.get(i); }
double avg = total / cost.size(); StringBuilder sb = new StringBuilder(); sb.append("平均响应时间:" + avg + "ms\r\n"); sb.append("95%响应时间:" + cost.get(percentile95Indx) + "ms\r\n"); return sb.toString(); }
class Task implements Runnable { private CyclicBarrier cb; private int requestCount;
public Task(CyclicBarrier cb, int requestCount) { this.cb = cb; this.requestCount = requestCount; }
@Override public void run() { // TODO Auto-generated method stub try { // 等待线程准备好 cb.await(); startSending(requestCount); } catch (InterruptedException | BrokenBarrierException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { delThread(); } } }
private void delThread() { currentThreadCount--; }
public void startSending(int requestCount) throws IOException { // 每条线程执行requestCount次 for (int i = 0; i < requestCount; i++) { this.cost.add(send()); } }
private long send() throws MalformedURLException { HttpURLConnection connection = null; InputStream is = null; OutputStream os = null; BufferedReader br = null; URL url = new URL(this.requestUrl); long startTime = 0; long endTime; try { connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setConnectTimeout(15000); connection.setReadTimeout(60000); connection.setDoOutput(true); connection.setDoInput(true); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
startTime = System.currentTimeMillis(); // 获取开始时间 os = connection.getOutputStream(); if (connection.getResponseCode() == 200) { is = connection.getInputStream(); br = new BufferedReader(new InputStreamReader(is, "UTF-8")); StringBuffer sbf = new StringBuffer(); String temp = null; while ((temp = br.readLine()) != null) { sbf.append(temp); sbf.append("\r\n"); }// System.out.println(sbf.toString()); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { endTime = System.currentTimeMillis(); // 获取结束时间 if (null != br) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != os) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != is) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } connection.disconnect(); } return endTime - startTime; }}
复制代码

PerformanceTest

package week7;
import junit.framework.TestCase;
public class PeformanceTest extends TestCase { private int parCount; private int reqTotalCount; private String reqUrl;
@Override protected void setUp() { this.parCount = 10; this.reqTotalCount = 100; this.reqUrl = "https://www.baidu.com"; StringBuilder sb = new StringBuilder(); sb.append("并发数:" + this.parCount + "\r\n"); sb.append("请求总数:" + this.reqTotalCount + "\r\n"); sb.append("压测URL:" + this.reqUrl + "\r\n"); System.out.println(sb.toString()); }
public void testPerformance() { PerformenceBox box = new PerformenceBox(this.parCount, this.reqTotalCount, this.reqUrl); try { box.Execute(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(box.outputPerformance()); }}
复制代码


发布于: 2020 年 07 月 22 日阅读数: 54
用户头像

还未添加个人签名 2020.05.30 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营-week7-作业