性能压测练习

用户头像
Mars
关注
发布于: 2020 年 12 月 06 日

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

性能压测分为如下三个阶段:

性能测试阶段

1.       压力指标

l  系统设计规划的并发压力范围。

2.       性能指标

l  吞吐量近乎线性增加。

l  响应时间稍微延长。

3.       释义:

l  并发压力在范围内,不影响用户响应时间。

l  系统资源充足。

负载测试阶段

1.     压力指标

l  超出系统并发压力范围,但在服务器允许的范围。

2.     性能指标

l  吞吐量缓慢增加。

l  响应时间快速增大。

3.     释义

l  继续加压,线程数量增多,开始争抢CPU、锁、I/O等资源,吞吐量增加缓慢。

l  受限服务器资源紧张,线程开始出现等待情况,导致响应时间延长。

压力测试阶段

1.     压力指标

l  超出服务器允许的负荷范围。

2.     性能指标

l  吞吐量开始下降。

l  响应时间急剧变长,直至系统崩溃。

3.     释义

l  当系统资源严重不足,导致大量线程等待时间更长。

l  当响应时间变长后,线程数也会不断增多。线程增长又导致内存出现不足,内存不足时,会把数据临时置换到硬盘换上,耗时更长。

l  处理用户请求时间变长,吞吐量降低。

l  随着处理能力变慢,但请求量一直在增加,最终CPU、内存、I/O等资源全部耗尽,最终系统崩溃。

 

java编写的一个 Web 性能压测工具,输入参数:URL,请求总次数,并发数。输出参数:平均响应时间,95% 响应时间。用这个测试工具以 10 并发、100 次请求压测 www.jd.com

@Slf4j
public class PerformanceTool {
private final ThreadPoolExecutor executor;
public PerformanceTool(int numOfThreads) {
this.executor = new ThreadPoolExecutor(numOfThreads, numOfThreads, 1, TimeUnit.MINUTES,
new LinkedBlockingDeque<>(10000), new PerformanceThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
}
public CompletableFuture<Result> run(String url, int nums){
return CompletableFuture.supplyAsync(() -> {
Result result = null;
CountDownLatch latch = new CountDownLatch(nums);
List<Integer> responseTimeList = Lists.newArrayList();
int loop = 0;
while (loop < nums) {
executor.submit(() -> {
HttpUriRequest request = new HttpGet(url);
try {
long start = System.currentTimeMillis();
int codeResult = HttpClients.createDefault()
.execute(request)
.getStatusLine()
.getStatusCode();
long end = System.currentTimeMillis();
responseTimeList.add((int) (end-start));
} catch (IOException e) {
log.error("http has error !",e);
}
latch.countDown();
});
++loop;
}
try {
latch.await();
} catch (InterruptedException e) {
log.error("Interrupted has error !",e);
}
return new Result(responseTimeList);
});
}
public static void main(String[] args) {
PerformanceTool performanceTool = new PerformanceTool(10);
CompletableFuture<Result> completableFuture = performanceTool.run("http://www.jd.com", 100);
try {
Result result = completableFuture.get();
log.info("AVG : "+ result.getAvg());
log.info("RT_95% : " + result.getRt_95Percentage());
} catch (InterruptedException e) {
log.error("InterruptedException has error !", e);
} catch (ExecutionException e) {
log.error("ExecutionException has error !", e);
}
}
}
class PerformanceThreadFactory implements ThreadFactory {
private ThreadGroup group;
private final String namePrefix;
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final AtomicInteger threadNumber = new AtomicInteger(1);
public PerformanceThreadFactory() {
SecurityManager securityManager = new SecurityManager();
this.group = securityManager.getThreadGroup();
StringBuilder sb = new StringBuilder();
sb.append("Performance-pool-").append(poolNumber.getAndIncrement())
.append("-thread-");
this.namePrefix = sb.toString();
}
/**
* Constructs a new {@code Thread}. Implementations may also initialize
* priority, name, daemon status, {@code ThreadGroup}, etc.
*
* @param r a runnable to be executed by new thread instance
* @return constructed thread, or {@code null} if the request to
* create a thread is rejected
*/
@Override
public Thread newThread(Runnable r) {
return new Thread(this.group, r,
this.namePrefix + this.threadNumber.getAndIncrement(), 0L);
}
}
class Result {
private List<Integer> responseTimeList;
private Double avg;
private Integer rt_95Percentage;
public Result(List<Integer> responseTimeList) {
this.responseTimeList = responseTimeList;
cal();
}
private void cal(){
if(CollectionUtils.isNotEmpty(responseTimeList)) {
int sum = responseTimeList.stream()
.mapToInt(Integer::shortValue)
.sum();
this.avg = sum * 1d / responseTimeList.size();
Collections.sort(responseTimeList);
rt_95Percentage = responseTimeList.get((int) (responseTimeList.size() * 0.95)-1);
}
}
public List<Integer> getResponseTimeList() {
return (List<Integer>) Collections.unmodifiableCollection(responseTimeList);
}
public void setResponseTimeList(List<Integer> responseTimeList) {
this.responseTimeList = responseTimeList;
}
public Double getAvg() {
return avg;
}
public void setAvg(Double avg) {
this.avg = avg;
}
public Integer getRt_95Percentage() {
return rt_95Percentage;
}
public void setRt_95Percentage(Integer rt_95Percentage) {
this.rt_95Percentage = rt_95Percentage;
}
}

运行结果:

AVG : 475.35
RT_95% : 2291



发布于: 2020 年 12 月 06 日阅读数: 369
用户头像

Mars

关注

还未添加个人签名 2018.06.12 加入

还未添加个人简介

评论

发布
暂无评论
性能压测练习