压测工具试验

用户头像
独孤魂
关注
发布于: 2020 年 07 月 23 日
压测工具试验

一、性能压测的时候,随着并发压力的增加,系统响应时间和吞吐量如何变化,为什么?



随着压力增加:

1、并发量首先上涨,系统稳定运行

2、当并发量涨到一定程度后,RT开始上涨,并发量则不再上涨,这时候系统处于最佳运行状态

3、并发量再次增长时,系统出现过载,RT直线上涨,TPS下跌,因为这时系统CPU、内存/IO等物理资源过渡消耗,处理能力下降,造成请求积压

避免系统过载的方法就是限流,阈值为系统最大并发量



二、用你熟悉的编程语言写一个 web 性能压测工具,输入参数:URL,请求总次数,并发数。输出参数:平均响应时间,95% 响应时间。用这个测试工具以 10 并发、100 次请求压测 www.baidu.com。

程序设计:

1、运行实际测试内容模块urlInvoker

2、多线程并发模块

3、性能统计模块

package com.hyy.test;

import lombok.Data;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.*;

// 性能压测的时候,随着并发压力的增加,系统响应时间和吞吐量如何变化,为什么?
// 用你熟悉的编程语言写一个 web 性能压测工具,输入参数:URL,请求总次数,并发数。
// 输出参数:平均响应时间,95% 响应时间。用这个测试工具以 10 并发、100 次请求压测 www.baidu.com。
//程序设计
//1、运行实际测试内容模块urlInvoker
//2、多线程并发模块
//3、性能统计模块
public class PostTest {

RestTemplate restTemplate = new RestTemplate();

public static void main(String[] args) {
PostTest postTest = new PostTest();
postTest.test();
}

public void test(){
TestRequest testRequest = new TestRequest();
testRequest.setConcurrentCount(10);
testRequest.setReqCount(100);
testRequest.setTarget("http://www.baidu.com");
Monitor monitor = doTest(testRequest);
System.out.println("成功次数:"+monitor.getSuccess()+" 失败次数:"+monitor.getFail()+" 异常次数:"+monitor.getException());
System.out.println("平均耗时="+getAvgTime(monitor)+" 95%耗时="+getMostTime(monitor));
}

/**
* 根据测试入参开始测试
* @param testRequest
* @return
*/
public Monitor doTest(TestRequest testRequest) {
ExecutorService executorService = Executors.newFixedThreadPool(testRequest.getConcurrentCount());
int count = testRequest.getReqCount();
InvokeTarget invokeTarget = new UrlInvoke();
Monitor monitor = new Monitor();
for(int i=0;i<count;i++){
long start = System.currentTimeMillis();
Future<RespStatus> f = executorService.submit(new Invoke(testRequest,invokeTarget));
RespStatus respStatus = null;
try {
respStatus = f.get();
}catch(Exception e){
respStatus = RespStatus.EXCEPTIOIN;
e.printStackTrace();
}
long end = System.currentTimeMillis();
monitor.appendResult(respStatus,end-start);
}
return monitor;
}

private double getAvgTime(Monitor monitor){
long totalTime = 0;
Map<String,Long> map = new HashMap();
map.put("totalTime",0l);
monitor.costTimeList.forEach((a)->{
map.put("totalTime",map.get("totalTime")+a );
});
return Double.valueOf(map.get("totalTime"))/monitor.getTotal();
}

/**
* 对耗时排序,取前95%耗时
* @param monitor
* @return
*/
private double getMostTime(Monitor monitor){
Collections.sort(monitor.costTimeList);
double countD = monitor.getTotal() * 0.95;
int count = (int)countD;
Map<String,Long> map = new HashMap();
map.put("totalTime",0l);
map.put("count",0l);
monitor.costTimeList.forEach((a)->{
if(map.get("count") < count){
map.put("totalTime",map.get("totalTime")+a );
map.put("count",map.get("count")+1 );
}
});
return Double.valueOf(map.get("totalTime"))/count;
}

enum RespStatus{
SUCCESS(1),FAIL(2),EXCEPTIOIN(3);
private int status;
RespStatus(int status){
this.status = status;
}
}
@Data
class TestRequest{
private int concurrentCount = 1;
private int reqCount = 1;
private String testType;//测试类型
private String target;
}
@Data
class Monitor{
private volatile int success ;
private volatile int fail;
private volatile int exception;
private volatile int total;
List<Long> costTimeList = new ArrayList<Long>();
public Monitor appendResult(RespStatus resp,long time){
if(resp == RespStatus.SUCCESS){
this.success ++;
}else if(resp == RespStatus.FAIL){
this.fail ++;
}else{
this.exception++;
}
costTimeList.add(time);
total++;
return this;
}
}
interface InvokeTarget{
public RespStatus invoke(TestRequest testRequest);
}

/**
* 执行测试类
*/
class UrlInvoke implements InvokeTarget{
public RespStatus invoke(TestRequest testRequest) {
return urlHandler(testRequest.getTarget());
}
public RespStatus urlHandler(String url){
RespStatus respStatus = RespStatus.FAIL;
ResponseEntity resp = null;
try {
resp = restTemplate.postForEntity(url,null,String.class);
if(resp.getStatusCode() == HttpStatus.OK){
respStatus = RespStatus.SUCCESS;
}
}catch (Exception e){
respStatus = RespStatus.EXCEPTIOIN;
e.printStackTrace();
}
return respStatus;
}
}
class Invoke implements Callable{
private TestRequest testRequest;
private InvokeTarget invokeTarget;
public Invoke(TestRequest testRequest,InvokeTarget invokeTarget){
this.testRequest = testRequest;
this.invokeTarget = invokeTarget;
}
public Object call() throws Exception {
return invokeTarget.invoke(testRequest);
}
}
}




测试1000次结果



发布于: 2020 年 07 月 23 日 阅读数: 14
用户头像

独孤魂

关注

还未添加个人签名 2019.04.10 加入

还未添加个人简介

评论

发布
暂无评论
压测工具试验