架构师训练营 - 命题作业 第 7 周
发布于: 2020 年 07 月 22 日
用你熟悉的编程语言写一个 web 性能压测工具,输入参数:URL,请求总次数,并发数。输出参数:平均响应时间,95% 响应时间。用这个测试工具以 10 并发、100 次请求压测 www.baidu.com。
1、先定义输入类:
package cn.yepeng.dto;import lombok.Data;@Datapublic class TestInputDto { /** * 测试地址 */ private String url; /** * 总请求数 */ private long requestTime; /** * 总并发数 */ private long concurrencyNum; /** * 每个线程要请求的次数. * 不考虑除不断的情况 * @return 次数 */ public long getTimePerThread() { return requestTime / concurrencyNum; } @Override public String toString() { return String.format("压测地址: %s 压测次数: %s 并发数: %s", url, requestTime, concurrencyNum); }}
2、定义输出类:
package cn.yepeng.dto;import lombok.Data;import lombok.Synchronized;import java.util.Map;import java.util.SortedMap;import java.util.TreeMap;@Datapublic class TestOutputDto { /** * 收集所有的请求时长 */ private SortedMap<Long, Long> map = new TreeMap<>(); @Synchronized public void putTime(long time) { map.put(time, 0L); } @Override public String toString() { long totalTime = 0; // 总的请求时长 long time95 = 0; // 95分位请求时长 long begin95 = map.size() * 95 / 100; // 95分位请求所在的索引位置 long idx = 0; for (Map.Entry<Long, Long> item : map.entrySet()) { if (idx == begin95) time95 = item.getKey(); totalTime += item.getKey(); idx++; } long avg = totalTime / map.size(); return String.format("压测结果:平均响应时间: %s纳秒 95分位响应时间: %s纳秒", avg, time95); }}
3、定义压测类:
package cn.yepeng;import cn.yepeng.dto.TestInputDto;import cn.yepeng.dto.TestOutputDto;import cn.yepeng.utils.HttpHelper;import lombok.Synchronized;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class ForTestService implements Runnable { private TestInputDto inputDto; private int threadNum; TestOutputDto ret = new TestOutputDto(); public ForTestService(TestInputDto inputDto) { this.inputDto = inputDto; } public TestOutputDto startTest() throws InterruptedException { // 抛弃第一次请求,避免DNS解析等损耗 sendRequest(); ExecutorService pool = Executors.newCachedThreadPool(); // 并行启动ConsurrencyNum个线程 for (int i = 0; i < inputDto.getConcurrencyNum(); i++) { pool.execute(this); } // 等待任务完成 do { Thread.sleep(10000); System.out.println(threadNum); } while (threadNum > 0); pool.shutdown(); return ret; } @Override public void run() { long perTime = inputDto.getTimePerThread(); addThread(); try { // 每个线程顺序执行请求 for (int requestIdx = 0; requestIdx < perTime; requestIdx++) { long costTime = sendRequest(); ret.putTime(costTime); } } catch (Exception exp) { System.out.println("有线程出错了:" + exp.getMessage()); } finally { decThread(); } } @Synchronized private void addThread() { threadNum++; } @Synchronized private void decThread() { threadNum--; } /** * 发请求 * @return 返回请求耗时,纳秒 */ private long sendRequest() { long beginTime = System.nanoTime(); HttpHelper.GetPage(inputDto.getUrl(), ""); return System.nanoTime() - beginTime; }}
5、最终输出结果:
请输入测试地址,默认值 https://www.baidu.com/: 请输入总请求次数,默认值 100: 请输入并发数,默认值 10: 压测地址: https://www.baidu.com/ 压测次数: 100 并发数: 10 开始测试0测试完成: 压测结果:平均响应时间: 36782823纳秒 95分位响应时间: 119898912纳秒
划线
评论
复制
发布于: 2020 年 07 月 22 日阅读数: 51
叶鹏
关注
还未添加个人签名 2018.09.25 加入
还未添加个人简介
评论 (1 条评论)