1
性能测试
发布于: 2020 年 07 月 22 日
一、作业内容
用你熟悉的编程语言写一个 web 性能压测工具,输入参数:URL,请求总次数,并发数。输出参数:平均响应时间,95% 响应时间。用这个测试工具以 10 并发、100 次请求压测 www.baidu.com
二、代码实现
1、首先定义单次请求的TestTask
/** * 测试请求task */ static class TestTask implements Callable<Long> { private CyclicBarrier barrier; private String url; public TestTask(String url, CyclicBarrier barrier) { this.url = url; this.barrier = barrier; } @Override public Long call() { Long duration; try { HttpClient httpClient = createClient(); HttpGet httpGet = new HttpGet(url); barrier.await(5, TimeUnit.SECONDS); Long start = System.currentTimeMillis(); httpClient.execute(httpGet); Long end = System.currentTimeMillis(); duration = end - start; } catch (Exception e) { System.out.println("test_task error," + e.toString()); duration = -1L; } return duration; } }
2、并发执行请求的测试代码如下:
public static Map<String, Long> concurrencyTest(int count, String url) { // 初始化CyclicBarrier,通过barrier去保证各线程同时对url发起请求 CyclicBarrier barrier = new CyclicBarrier(count, () -> System.out.println("request current start")); //用于存储数据计算统计的结果 Map<String, Long> statistics = new HashMap<>(); statistics.put("total", Long.valueOf(count)); List<FutureTask<Long>> futureList = new ArrayList<>(); try { for (int i = 0; i < count; i++) { // 基于TestTask够条件FutureTask,并创建线程进行执行 FutureTask<Long> futureTask = new FutureTask<>(new TestTask(url, barrier)); new Thread(futureTask).start(); futureList.add(futureTask); } } catch (Exception e) { System.out.println("concurrency test error," + e.toString()); } if (CollectionUtils.isNotEmpty(futureList)) { List<Long> durations = new ArrayList<>(); for (int i = 0; i < count; i++) { try { Long duration = futureList.get(i).get(); if (duration > 0L) { durations.add(duration); } } catch (Exception e) { System.out.printf("future error,", e.toString()); } } Collections.sort(durations); int index = (int) Math.floor(durations.size() * 0.95); Long per95 = durations.get(index - 1); Long avg = durations.stream().collect(Collectors.averagingLong(x -> x)).longValue(); statistics.put("success", Long.valueOf(durations.size())); statistics.put("per95", per95); statistics.put("avg", avg); } return statistics; }
3、封装HttpClient的构建代码
// 构建 HttpClient private static HttpClient createClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException { RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.create(); ConnectionSocketFactory plainConnectionSocketFactory = new PlainConnectionSocketFactory(); registryBuilder.register("http", plainConnectionSocketFactory); KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); //信任任何链接 SSLContext sslContext = SSLContexts.custom().useTLS().loadTrustMaterial(trustStore, (x509Certificates, s) -> true).build(); LayeredConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); registryBuilder.register("https", sslSF); Registry<ConnectionSocketFactory> registry = registryBuilder.build(); PoolingHttpClientConnectionManager clientConnectionManager = new PoolingHttpClientConnectionManager(registry); clientConnectionManager.setMaxTotal(2); clientConnectionManager.setDefaultMaxPerRoute(20); return HttpClientBuilder.create().setConnectionManager(clientConnectionManager).build(); }
4、客户端调动代码如下:
public static void main(String[] args) { String requestUrl = "https://www.taobao.com/"; int count1 = 10; int count2 = 100; Map<String, Long> result1 = RequestTest.concurrencyTest(count1, requestUrl); Map<String, Long> result2 = RequestTest.concurrencyTest(count2, requestUrl); showData(result1); showData(result2); } public static void showData(Map<String, Long> statistics) { StringBuilder builder = new StringBuilder(); builder.append("并发请求总数:"); builder.append(statistics.get("total")); builder.append("\n"); builder.append("成功的请求数:"); builder.append(statistics.get("success")); builder.append("\n"); builder.append("95百分位耗时:"); builder.append(statistics.get("per95")); builder.append("ms"); builder.append("\n"); builder.append("平均请求耗时:"); builder.append(statistics.get("avg")); builder.append("ms"); builder.append("\n"); System.out.println(builder.toString()); }
5、最终的执行代码如下:
并发请求总数:10成功的请求数:1095百分位耗时:430ms平均请求耗时:394ms并发请求总数:100成功的请求数:10095百分位耗时:4347ms平均请求耗时:2141ms
划线
评论
复制
发布于: 2020 年 07 月 22 日阅读数: 58
考尔菲德
关注
还未添加个人签名 2018.04.19 加入
还未添加个人简介
评论 (1 条评论)