周练习 7
发布于: 2020 年 11 月 08 日
性能压测的时候,随着并发压力的增加,系统响应时间和吞吐量如何变化,为什么?
一个良好的系统随着并发压力的增加,系统响应时间会先缓慢增加,但随着系统压力接近或超过极限,系统的响应时间的增加量将迅速增多,响应时间-并发压力的曲线将呈现类似指数的形状;
吞吐量则先随着并发压力的增加而快速增加,然后到达拐点吞吐量增长放缓,接着达到顶点,之后随着并发压力的增加反而下降;
系统资源是有限的,最开始并发压力低的时候系统可能还有不少空闲资源,随着并发压力的上升这些资源将逐渐利用,但达到峰值后就无法同时处理这么多请求了,不做处理的话一般会阻塞后续的请求
用你熟悉的编程语言写一个 Web 性能压测工具,输入参数:URL,请求总次数,并发数。输出参数:平均响应时间,95% 响应时间。用这个测试工具以 10 并发、100 次请求压测 www.baidu.com。
Task类:
package com.example.week7;import com.example.redis.JedisFactory;import redis.clients.jedis.Jedis;import java.net.URL;import java.net.URLConnection;public class TestUrlTask implements Runnable{ private static final String RESULT_COLLECTION_KEY = "testUrlResult"; private String url; private int accessNumber; @Override public void run() { try { Jedis jedis = JedisFactory.prepareJedis(); for (int i = 0; i < accessNumber; i++) { URL targetUrl = new URL(url); URLConnection urlConnection = targetUrl.openConnection(); long startTime = System.currentTimeMillis(); urlConnection.connect(); long endTime = System.currentTimeMillis(); long cost = endTime - startTime; String currentKey = this.getCurrentMember(i); jedis.zadd(RESULT_COLLECTION_KEY, cost, currentKey); } } catch (Exception e) { e.printStackTrace(); } finally { Thread.currentThread().interrupt(); } } private String getCurrentMember(int i) { Thread currentThread = Thread.currentThread(); String currentThreadName = currentThread.getName(); long currentThreadId = currentThread.getId(); String currentKey = String.format("%s_%s_%d", currentThreadName, currentThreadId + "", i); return currentKey; } public TestUrlTask(String url, int accessNumber) { this.url = url; this.accessNumber = accessNumber; }}
测试类:
package com.example.week7;import com.example.redis.JedisFactory;import redis.clients.jedis.Jedis;import java.util.Set;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;public class TestUrl { public static void main(String[] args) throws Exception { String url = args[0]; int concurrentNumber = Integer.parseInt(args[1]); int eachAccessNumber = Integer.parseInt(args[2]); ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(concurrentNumber, concurrentNumber, 3, TimeUnit.SECONDS, new LinkedBlockingQueue()); for (int i = 0; i < concurrentNumber; i++) { TestUrlTask testUrlTask = new TestUrlTask(url, eachAccessNumber); threadPoolExecutor.execute(testUrlTask); } while (true) { if(threadPoolExecutor.getActiveCount() == 0) { break; } } threadPoolExecutor.getQueue().clear(); threadPoolExecutor.shutdown(); showResult(); System.out.println("all done"); } private static void showResult() { Jedis jedis = JedisFactory.prepareJedis(); Set<String> zrange = jedis.zrange(TestUrlTask.RESULT_COLLECTION_KEY, 0, -1); Long count = jedis.zcard(TestUrlTask.RESULT_COLLECTION_KEY); Double costTime = 0D; Long counter = 0L; Long targetTitlePosition = count / 100 * 95; String targetTitleMember = ""; for (String member : zrange) { Double zscore = jedis.zscore(TestUrlTask.RESULT_COLLECTION_KEY, member); costTime += zscore; counter++; if (counter.equals(targetTitlePosition)) { targetTitleMember = member; } } Double averageCostTime = costTime / count; Double titleCostTime = jedis.zscore(TestUrlTask.RESULT_COLLECTION_KEY, targetTitleMember); System.out.println("平均响应时间:"+ averageCostTime +" ;95% 响应时间: " + titleCostTime); }}
控制台输出取样:
平均响应时间:21.405 ;95% 响应时间: 23.0all done
划线
评论
复制
发布于: 2020 年 11 月 08 日阅读数: 59
何毅曦
关注
还未添加个人签名 2019.03.20 加入
还未添加个人简介
评论