写点什么

架构师训练营 1 期 - 第七周作业(vaik)

用户头像
行之
关注
发布于: 2020 年 11 月 08 日
架构师训练营 1 期 - 第七周作业(vaik)
  1. 性能压测的时候,随着并发压力的增加,系统响应时间和吞吐量如何变化,为什么?

答:性能压则的时候,随并并压力的增加,系统响应时间开始水平线,然后线性上升,最后达到性能极限时,无响应或会响应超时,而吞吐量则是一个抛物性形状,先升高,达到最高点,相当于系统性能极限,然后开始下降,最终到系统崩溃。


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

工具由五个类组成

  • main 方法入口类:SimplePressureTestDemo

  • 任务类:Task

  • 任务结果类:TaskResult

  • 任务线程执行类:TaskRunner

  • 请求发送类:HttpRequestUtil

添加两个 Maven 类库引用

  • org.apache.httpcomponents.httpclient:4.5.12

  • org.projectlombok.lombok:1.18.12

命令行传入三个参数: url concurrentNumber requestNumber

执行结果:


package com.vaik.pressuretest;
import lombok.Data;import java.util.List;
@Datapublic class Task { //请求的URL private String url; //开启线程数 private int threadNumber; //总请求数量 private int requestNumber; //已完成请求数 private int completedNumber; //请求结果集 private List<TaskResult> results;}
复制代码


package com.vaik.pressuretest;import lombok.Data;
@Datapublic class TaskResult { //开始时间戳 private long startTime; //结束时间戳 private long endTime; //消耗时间长 private long consumeTime; //任务号 private long taskNumber; //执行任务线程 private String runThreadName; //执行结果 private String msg;}
复制代码


package com.vaik.pressuretest;
public class TaskRunner implements Runnable { private static final Object obj = new Object(); private Task task; public TaskRunner(Task task){ this.task = task; }
@Override public void run() { while (!isEnd()){ synchronized (obj){ task.setCompletedNumber(task.getCompletedNumber()+1); //System.out.println("setCompletedNumber "+task.getCompletedNumber()); } TaskResult taskResult = new TaskResult(); long startTime = System.currentTimeMillis(); taskResult.setStartTime(startTime); //System.out.println("start HttpRequestUtil"); String res = HttpRequestUtil.get(task.getUrl()); //System.out.println("HttpRequestUtil response:" + res); if(res.isEmpty()){ taskResult.setMsg(Thread.currentThread().getName()+" has exception, taskNumber"+(task.getCompletedNumber()+1)); }else{ taskResult.setMsg(Thread.currentThread().getName()+ " success taskNumber:"+(task.getCompletedNumber()+1)); } long endTime = System.currentTimeMillis(); taskResult.setEndTime(endTime); taskResult.setConsumeTime(endTime-startTime); taskResult.setTaskNumber(task.getCompletedNumber()+1); taskResult.setRunThreadName(Thread.currentThread().getName()); task.getResults().add(taskResult); //System.out.println("end HttpRequestUtil"); } }
private boolean isEnd(){ synchronized (obj) { boolean bl = false; if (task.getCompletedNumber() >= task.getRequestNumber()) { bl = true; } return bl; } }}
复制代码


package com.vaik.pressuretest;
import java.util.ArrayList;import java.util.Comparator;import java.util.List;
public class SimplePressureTestDemo { public static void main(String[] args) throws InterruptedException { if(args.length == 3) { String url = args[0]; int threadNumber = Integer.parseInt(args[1]); int requestNumber = Integer.parseInt(args[2]); com.vaik.pressuretest.Task task = new com.vaik.pressuretest.Task(); task.setUrl(url); task.setThreadNumber(threadNumber); task.setRequestNumber(requestNumber); task.setCompletedNumber(0); List<TaskResult> list = new ArrayList<>(); task.setResults(list); executeTask(task); while(task.getCompletedNumber()<task.getRequestNumber()){ Thread.sleep(1000); printResult(task); }
}else{ System.out.println("参数个数不正确,正确格式 url concurrentNumber requestNumber"); } }
public static void executeTask(Task task){ System.out.println("Start executeTask"); for(int i =0;i<task.getThreadNumber();i++){ TaskRunner taskRunner = new TaskRunner(task); Thread thread = new Thread(taskRunner); thread.setName("Thread#"+i); thread.start(); } }
public static void printResult(Task task){ List<TaskResult> results = task.getResults(); if(results.size()>0) { results.sort(Comparator.comparing(TaskResult::getConsumeTime)); double avg = results.stream().mapToDouble(TaskResult::getConsumeTime).average().getAsDouble(); System.out.println("总需发送请求:" + task.getRequestNumber() + " 实际完成请求:" + task.getCompletedNumber()); System.out.println("平均响应时间:" + avg+"毫秒"); if (results.size() > 95) System.out.println("95%响应时间:" + results.get(95).getConsumeTime()+"毫秒"); } }}
复制代码


package com.vaik.pressuretest;import org.apache.http.client.config.RequestConfig;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpPost;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.nio.charset.Charset;
/** * @author wanghang * @Description * @date: 2018/04/07 17:49 */public class HttpRequestUtil { private static CloseableHttpClient httpClient;
static { PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); cm.setMaxTotal(100); cm.setDefaultMaxPerRoute(20); cm.setDefaultMaxPerRoute(50); httpClient = HttpClients.custom().setConnectionManager(cm).build(); }
public static String get(String url) { CloseableHttpResponse response = null; BufferedReader in = null; String result = ""; try { HttpGet httpGet = new HttpGet(url); RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30000).setConnectionRequestTimeout(30000).setSocketTimeout(30000).build(); httpGet.setConfig(requestConfig); httpGet.setConfig(requestConfig); httpGet.addHeader("Content-type", "application/json; charset=utf-8"); httpGet.setHeader("Accept", "application/json"); response = httpClient.execute(httpGet); in = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); StringBuffer sb = new StringBuffer(""); String line = ""; String NL = System.getProperty("line.separator"); while ((line = in.readLine()) != null) { sb.append(line + NL); } in.close(); result = sb.toString(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (null != response) { response.close(); } } catch (IOException e) { e.printStackTrace(); } } return result; }
public static String post(String url, String jsonString) { CloseableHttpResponse response = null; BufferedReader in = null; String result = ""; try { HttpPost httpPost = new HttpPost(url); RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30000).setConnectionRequestTimeout(30000).setSocketTimeout(30000).build(); httpPost.setConfig(requestConfig); httpPost.setConfig(requestConfig); httpPost.addHeader("Content-type", "application/json; charset=utf-8"); httpPost.setHeader("Accept", "application/json"); httpPost.setEntity(new StringEntity(jsonString, Charset.forName("UTF-8"))); response = httpClient.execute(httpPost); in = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); StringBuffer sb = new StringBuffer(""); String line = ""; String NL = System.getProperty("line.separator"); while ((line = in.readLine()) != null) { sb.append(line + NL); } in.close(); result = sb.toString(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (null != response) { response.close(); } } catch (IOException e) { e.printStackTrace(); } } return result; }}
复制代码


用户头像

行之

关注

还未添加个人签名 2018.09.18 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营 1 期 - 第七周作业(vaik)