Week 07 命题作业
1.性能压测的时候,随着并发压力的增加,系统响应时间和吞吐量如何变化,为什么?
解答:
响应时间:
指应用系统从发出请求开始到收到最后响应数据所需要的时间。响应时间是
系统最重要的性能指标,直观的反映了系统的“快慢”。
并发数:
系统能够同时处理请求的数目,这个数字也反映了系统的负载特性。对于网站而言,并发数即系统并发用户数,指同时提交请求的用户数目,与此相对应,还有在线用户数(当前登录系统的用户数)和系统用户数(可能访问系统的总用户数)。
吞吐量:
指单位时间内系统处理的请求的数量,体现件系统的处理能力。
对于网站,可以用“请求数/秒”或是“页面数/秒”来衡量,也可以用“访问人数/天”或是“处理的
业务数小时”等来衡量。
TPS (每秒事务数)也是吞吐量的一个指标,
此外还有HPS ( 每秒HTTP请求数),
QPS (每秒查询数)等。
下面是吞吐量的计算公式:
吞吐量=( 1000/响应时间ms ) x并发数
上面的公式看起来并发数越高,响应时间越短,系统吞吐量就越大;但实际上,并发数并不是无限增加吞吐量就越大了,因为系统处理能力是有极限的,到达极限后,响应时间就会不断的增加,这样吞吐量就会不断下降了。
资源消耗与TPS性能曲线图:
并发用户访问响应时间曲线图:
由此可见,随着并发数的不断增大,吞吐量有以下几种情况发生:
a.当系统处于B点之前时,系统的吞吐量增加显著;
b.当系统处于B点与C点之间时,由于响应时间开始明显增加,导致系统的吞吐量增长放缓;
c.当系统处于C点和D点之间时,由于系统已经过了最大负载点,导致响应时间急剧增加,这样就使得系统的吞吐量开始下降,直到D点系统崩溃为止。
2.用你熟悉的编程语言写一个web性能压测工具,输入参数: URL,请求总次数,并发数。
输出参数:平均响应时间,95%响应时间。用这个测试工具以10并发、100次请求压测www .baidu.com。
解答:
核心测试类:
import java.io.IOException;import java.util.ArrayList;import java.util.Collections;import java.util.List;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore;import org.apache.http.client.ClientProtocolException;/** * 模拟压力测试 * * @author YX * * */public class StressTest3 { // 测试接口地址 public static final String testUrl = "https://www.baidu.com"; // 总请求个数 public static final int requestTotal = 100; // 同一时刻最大的并发线程的个数 public static final int concurrentThreadNum = 10; public static void main(String[] args) throws InterruptedException { List<Long> responseTimeList = Collections.synchronizedList(new ArrayList<Long>()); ExecutorService executorService = Executors.newCachedThreadPool(); CountDownLatch countDownLatch = new CountDownLatch(requestTotal); Semaphore semaphore = new Semaphore(concurrentThreadNum); for (int i = 0; i< requestTotal; i++) { executorService.execute(()->{ try { semaphore.acquire(); long startTime = System.currentTimeMillis(); String result = testRequestUri(); long endTime = System.currentTimeMillis(); responseTimeList.add(endTime - startTime); //System.out.println((endTime - startTime)+"返回接口调用结果:"+result); semaphore.release(); } catch (InterruptedException | IOException e) { e.printStackTrace(); } countDownLatch.countDown(); }); } countDownLatch.await(); executorService.shutdown(); // 显示测试报告 countAndShowReport(responseTimeList); } //请求测试接口 private static String testRequestUri() throws ClientProtocolException, IOException { return HttpClientUtil.get(testUrl); } // 计算测试总耗时及平均耗时,并显示测试报告 private static void countAndShowReport(List<Long> list){ long allTime = 0;// 总响应时间 long avgTime = 0;// 平均响应时间 long resp95Time = 0;// 95%响应时间 // 求总时间 for(Long temp : list){ allTime += temp; } // 求平均响应时间 avgTime = Math.round(allTime / list.size()); // 求95%响应时间 double p = 0.95; int n = list.size(); Collections.sort(list); double px = p*(n-1); int i = (int)Math.floor(px); double g = px - i; if(g==0){ resp95Time = list.get(0); }else{ resp95Time = (long)((1 - g) * list.get(i) + g * list.get(i+1)); } // 打印测试结果报告 System.out.println(testUrl+"========测试执行完毕,执行情况如下:"); System.out.println("总请求数:"+requestTotal); System.out.println("并发数:"+concurrentThreadNum); System.out.println("平均响应时间(毫秒):"+avgTime); System.out.println("95%响应时间(毫秒):"+resp95Time); }}/*其中一次的打印报告:https://www.baidu.com========测试执行完毕,执行情况如下:总请求数:100并发数:10平均响应时间(毫秒):45595%响应时间(毫秒):2935 */
HTTP请求工具类:
import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.NameValuePair;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.HttpClient;import org.apache.http.client.config.RequestConfig;import org.apache.http.client.entity.UrlEncodedFormEntity;import org.apache.http.client.methods.HttpDelete;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpPost;import org.apache.http.client.methods.HttpPut;import org.apache.http.client.utils.URLEncodedUtils;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.HttpClients;import org.apache.http.message.BasicNameValuePair;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.*;import java.net.URI;import java.net.URLEncoder;import java.util.ArrayList;import java.util.List;import java.util.Map;import java.util.Set;/** * Http请求封装工具类 */public class HttpClientUtil { private static final Logger logger = LoggerFactory.getLogger(HttpClientUtil.class); /** * 封装HTTP POST方法 * * @param * @param * @return * @throws ClientProtocolException * @throws IOException */ public static String post(String url, Map<String, String> paramMap) throws ClientProtocolException, IOException { HttpClient httpClient = HttpClients.createDefault(); HttpPost httpPost = new HttpPost(url); //设置请求和传输超时时间 RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build(); httpPost.setConfig(requestConfig); List<NameValuePair> formparams = setHttpParams(paramMap); UrlEncodedFormEntity param = new UrlEncodedFormEntity(formparams, "UTF-8"); httpPost.setEntity(param); HttpResponse response = httpClient.execute(httpPost); logger.info("************{}", response); String httpEntityContent = getHttpEntityContent(response); logger.info("************{}", httpEntityContent); httpPost.abort(); logger.info("************{}", httpEntityContent); return httpEntityContent; } /** * 封装HTTP POST方法 * * @param * @param (如JSON串) * @return * @throws ClientProtocolException * @throws IOException */ public static String post(String url, String data) throws ClientProtocolException, IOException { HttpClient httpClient = HttpClients.createDefault(); HttpPost httpPost = new HttpPost(url); //设置请求和传输超时时间 RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build(); httpPost.setConfig(requestConfig); httpPost.setHeader("Content-Type", "text/json; charset=utf-8"); httpPost.setEntity(new StringEntity(URLEncoder.encode(data, "UTF-8"))); HttpResponse response = httpClient.execute(httpPost); String httpEntityContent = getHttpEntityContent(response); httpPost.abort(); return httpEntityContent; } /** * 封装HTTP GET方法 * * @param * @return * @throws ClientProtocolException * @throws IOException */ public static String get(String url) throws ClientProtocolException, IOException { HttpClient httpClient = HttpClients.createDefault(); HttpGet httpGet = new HttpGet(); //设置请求和传输超时时间 RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build(); httpGet.setConfig(requestConfig); httpGet.setURI(URI.create(url)); HttpResponse response = httpClient.execute(httpGet); String httpEntityContent = getHttpEntityContent(response); httpGet.abort(); return httpEntityContent; } /** * 封装HTTP GET方法 * * @param * @param * @return * @throws ClientProtocolException * @throws IOException */ public static String get(String url, Map<String, String> paramMap) throws ClientProtocolException, IOException { HttpClient httpClient = HttpClients.createDefault(); HttpGet httpGet = new HttpGet(); //设置请求和传输超时时间 RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build(); httpGet.setConfig(requestConfig); List<NameValuePair> formparams = setHttpParams(paramMap); String param = URLEncodedUtils.format(formparams, "UTF-8"); httpGet.setURI(URI.create(url + "?" + param)); HttpResponse response = httpClient.execute(httpGet); String httpEntityContent = getHttpEntityContent(response); httpGet.abort(); return httpEntityContent; } /** * 封装HTTP PUT方法 * * @param * @param * @return * @throws ClientProtocolException * @throws IOException */ public static String put(String url, Map<String, String> paramMap) throws ClientProtocolException, IOException { HttpClient httpClient = HttpClients.createDefault(); HttpPut httpPut = new HttpPut(url); //设置请求和传输超时时间 RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build(); httpPut.setConfig(requestConfig); List<NameValuePair> formparams = setHttpParams(paramMap); UrlEncodedFormEntity param = new UrlEncodedFormEntity(formparams, "UTF-8"); httpPut.setEntity(param); HttpResponse response = httpClient.execute(httpPut); String httpEntityContent = getHttpEntityContent(response); httpPut.abort(); return httpEntityContent; } /** * 封装HTTP DELETE方法 * * @param * @return * @throws ClientProtocolException * @throws IOException */ public static String delete(String url) throws ClientProtocolException, IOException { HttpClient httpClient = HttpClients.createDefault(); HttpDelete httpDelete = new HttpDelete(); //设置请求和传输超时时间 RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build(); httpDelete.setConfig(requestConfig); httpDelete.setURI(URI.create(url)); HttpResponse response = httpClient.execute(httpDelete); String httpEntityContent = getHttpEntityContent(response); httpDelete.abort(); return httpEntityContent; } /** * 封装HTTP DELETE方法 * * @param * @param * @return * @throws ClientProtocolException * @throws IOException */ public static String delete(String url, Map<String, String> paramMap) throws ClientProtocolException, IOException { HttpClient httpClient = HttpClients.createDefault(); HttpDelete httpDelete = new HttpDelete(); //设置请求和传输超时时间 RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build(); httpDelete.setConfig(requestConfig); List<NameValuePair> formparams = setHttpParams(paramMap); String param = URLEncodedUtils.format(formparams, "UTF-8"); httpDelete.setURI(URI.create(url + "?" + param)); HttpResponse response = httpClient.execute(httpDelete); String httpEntityContent = getHttpEntityContent(response); httpDelete.abort(); return httpEntityContent; } /** * 设置请求参数 * * @param * @return */ private static List<NameValuePair> setHttpParams(Map<String, String> paramMap) { List<NameValuePair> formparams = new ArrayList<NameValuePair>(); Set<Map.Entry<String, String>> set = paramMap.entrySet(); for (Map.Entry<String, String> entry : set) { formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } return formparams; } /** * 获得响应HTTP实体内容 * * @param response * @return * @throws IOException * @throws UnsupportedEncodingException */ private static String getHttpEntityContent(HttpResponse response) throws IOException, UnsupportedEncodingException { HttpEntity entity = response.getEntity(); if (entity != null) { InputStream is = entity.getContent(); BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8")); String line = br.readLine(); StringBuilder sb = new StringBuilder(); while (line != null) { sb.append(line + "\n"); line = br.readLine(); } return sb.toString(); } return ""; }}
卧石漾溪
还未添加个人签名 2020.05.04 加入
还未添加个人简介
评论