第七周作业
发布于: 2020 年 07 月 20 日
性能压测的时候,随着并发压力的增加,系统响应时间和吞吐量如何变化,为什么?
性能测试的几个阶段:性能测试(性能预期)、负载测试(最大负载)、压力测试(崩溃点)、稳定性测试(稳定运行)
在系统测试阶段,系统资源充裕,随着并发的增加,响应时间平稳,系统的吞吐量快速增加
在负载测试阶段,随着并发的压力增加,系统部分资源已经达极限,响应时间开始变长,
系统的吞吐量基本达到极限
在压力测试阶段,对超负载的系统继续增加并发,系统开始崩溃,响应时间急速增加直到完全失去响应,系统负载也快速下降
用你熟悉的编程语言写一个 web 性能压测工具,输入参数:URL,请求总次数,并发数。输出参数:平均响应时间,95% 响应时间。用这个测试工具以 10 并发、100 次请求压测 www.baidu.com。
代码如下:
/** * 请求 * @author zhaoct * @date 2020-07-20 9:25 */public class Request { /** * 请求URL */ private String url; /** * 请求总次数 */ private Integer requests; /** * 请求并发数 */ private Integer concurrency; public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public Integer getRequests() { return requests; } public void setRequests(Integer requests) { this.requests = requests; } public Integer getConcurrency() { return concurrency; } public void setConcurrency(Integer concurrency) { this.concurrency = concurrency; }}
/** * 执行结果 * * @author zhaoct * @date 2020-07-20 9:33 */public class Result implements Comparable<Result> { private Long startTime; private Long endTime; private Long executeTime; private int code; private Boolean isError; public Long getStartTime() { return startTime; } public void setStartTime(Long startTime) { this.startTime = startTime; } public Long getEndTime() { return endTime; } public void setEndTime(Long endTime) { this.endTime = endTime; } public Long getExecuteTime() { return this.endTime - this.startTime; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public Boolean getError() { return "200".equals(code); } @Override public int compareTo(Result result) { if(this.getExecuteTime() > result.getExecuteTime()) { return 1; }else if(this.getExecuteTime() < result.getExecuteTime()) { return -1; }else{ return 0; } }}
/** * http工具类 * @author zhaoct * @date 2020-07-20 9:25 */public class HttpUtil { /** * get 请求 * @param url * @return http response code * @throws Exception */ public static int doGet(String url) throws Exception{ CloseableHttpClient httpclient = HttpClients.createDefault(); HttpGet httpGet = new HttpGet(url); try (CloseableHttpResponse response = httpclient.execute(httpGet)) { //HttpEntity entity = response.getEntity(); //EntityUtils.consume(entity); return response.getCode(); } } /** * post 请求 * @param url * @param paramList * @return http response code * @throws Exception */ public static int doPost(String url, List<NameValuePair> paramList) throws Exception{ CloseableHttpClient httpclient = HttpClients.createDefault(); HttpPost httpPost = new HttpPost(url); httpPost.setEntity(new UrlEncodedFormEntity(paramList)); try (CloseableHttpResponse response = httpclient.execute(httpPost)) { //HttpEntity entity = response.getEntity(); //EntityUtils.consume(entity); return response.getCode(); } }}
/** * 模拟请求类 * @author zhaoct * @date 2020-07-20 9:25 */public class Engine { /** * 请求 */ private Request request = null; /** * 所有线程都准备好之后,再发起请求,防止线程启动时间带来误差 */ private CountDownLatch startCountDownLatch = null; /** * 等待所有线程执行完成后返回结果 */ private CountDownLatch endCountDownLatch = null; public Engine(Request request){ this.request = request; startCountDownLatch = new CountDownLatch(request.getConcurrency()); endCountDownLatch = new CountDownLatch(request.getConcurrency()); } public List<Result> execute(){ List<Result> list = Collections.synchronizedList(new ArrayList<>()); for(int i=0; i<request.getConcurrency(); i++){ //线程只需要执行一次任务,不需要创建线程池 new Thread( () -> { startCountDownLatch.countDown(); try { //等所有线程都启动了在执行,模拟并发 startCountDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } for(int j=0; j<request.getRequests(); j++){ int code = 0; long startTime = 0; long endTime = 0; try { startTime = System.currentTimeMillis(); code = HttpUtil.doGet(request.getUrl()); endTime = System.currentTimeMillis(); } catch (Exception e) { e.printStackTrace(); }finally { Result result = new Result(); result.setCode(code); result.setStartTime(startTime); result.setEndTime(endTime); list.add(result); } } endCountDownLatch.countDown(); } ).start(); } //所有线程都执行完了返回结果 try { endCountDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } return list; }}
/** * 统计数据类 * @author zhaoct * @date 2020-07-20 9:25 */public class Statistics { private List<Result> list = null; public Statistics(List<Result> list){ this.list = list; } public long getAvgRT(){ long sumRT = 0; for(Result result : list){ sumRT += result.getExecuteTime(); } return sumRT / list.size(); } public long get95PRT(){ //排序 Collections.sort(list); //95分位值 return list.get((int)(list.size() * 95 / 100) - 1).getExecuteTime(); }}
/** * 启动类 * @author zhaoct * @date 2020-07-20 9:25 */public class Main { /** * 启动方法 * @param args * -n 即requests,用于指定压力测试总共的执行次数 * -c 即concurrency,用于指定的并发数 */ public static void main(String[] args) { Request request = new Request(); request.setUrl(args[args.length-1]); for(int i=0; i<args.length; i++){ if("-n".equals(args[i])){ request.setRequests(Integer.parseInt(args[i+1])); }else if("-c".equals(args[i])){ request.setConcurrency(Integer.parseInt(args[i+1])); } } Engine engine = new Engine(request); List<Result> list = engine.execute(); Statistics statistics = new Statistics(list); System.out.println("平均响应时间:" + statistics.getAvgRT() + " ms "); System.out.println("95% 响应时间:" + statistics.get95PRT() + " ms "); }}
执行结果:
[root@VM_17_65_centos zhaoct]# java -jar performance-test-tool-1.0-SNAPSHOT-jar-with-dependencies.jar -n 100 -c 10 http://www.baidu.com
平均响应时间:36 ms
95% 响应时间:38 ms
划线
评论
复制
发布于: 2020 年 07 月 20 日 阅读数: 39
changtai
关注
还未添加个人签名 2018.04.30 加入
还未添加个人简介
评论