nGrinder源码分析:自动中断测试任务
来源:互联网 发布:美图秀秀软件旧版本 编辑:程序博客网 时间:2024/05/16 12:49
1.背景
在运行nGrinder任务时,会出现任务被系统中断,为什么会自动中断呢?是bug还是一种保护机制?本文通过源码分析的方式来解读。
2.源码分析
之前的一篇文章:性能测试工具 nGrinder 项目剖析及二次开发,介绍了nGrinder的整体架构,知道ngrinder-core/src/main/java/net/grinder/SingleConsole.java是将测试脚本发布到Agent并在其上执行性能测试,该类实现了收集测试过程中的采样数据,将数据分成两部分记录:
- 写入记录文件,供时序图展示(*.data和csv)
- 写入内存,供详细数据展示(
private Map<String, Object> statisticData
, 持久化到DB)
其中将采样数据写到第一部分(*.data和csv)的实现方法如下:
/* * (non-Javadoc) * * @see * net.grinder.console.model.SampleListener#update(net.grinder.statistics * .StatisticsSet, net.grinder.statistics.StatisticsSet) */ @Override public void update(final StatisticsSet intervalStatistics, final StatisticsSet cumulativeStatistics) { try { if (!capture) { return; } samplingCount++; long currentPeriod = cumulativeStatistics.getValue(getSampleModel() .getPeriodIndex()); setTpsValue(sampleModel.getTPSExpression().getDoubleValue( intervalStatistics)); checkTooLowTps(getTpsValues()); updateStatistics(intervalStatistics, cumulativeStatistics); // 将采样数据写入csv数据 // hugang writeIntervalCsvData(intervalStatistics); int interval = getSampleModel().getSampleInterval(); long gap = 1; if (samplingCount == 1) { lastSamplingPeriod = currentPeriod; } else { lastSamplingPeriod = lastSamplingPeriod + interval; gap = ((currentPeriod - lastSamplingPeriod) / interval); } // Adjust sampling delay.. run write data multiple times... when it // takes longer than 1 // sec. samplingLifeCycleListener .apply(new Informer<SamplingLifeCycleListener>() { @Override public void inform(SamplingLifeCycleListener listener) { listener.onSampling(getReportPath(), intervalStatistics, cumulativeStatistics); } }); for (int i = 0; i < (gap + 1); i++) { final boolean lastCall = (samplingCount == 1 && i == 0) || (samplingCount != 1 && i == gap); // 将采样数据写到*.data文件 // hugang writeIntervalSummaryData(intervalStatistics, lastCall); if (interval >= (MIN_SAMPLING_INTERVAL_TO_ACTIVATE_TPS_PER_TEST)) { writeIntervalSummaryDataPerTest( intervalStatisticMapPerTest, lastCall); } samplingLifeCycleFollowupListener .apply(new Informer<SamplingLifeCycleFollowUpListener>() { @Override public void inform( SamplingLifeCycleFollowUpListener listener) { listener.onSampling(getReportPath(), intervalStatistics, cumulativeStatistics, lastCall); } }); } checkTooManyError(cumulativeStatistics); lastSamplingPeriod = lastSamplingPeriod + (interval * gap); } catch (RuntimeException e) { LOGGER.error("Error occurred while updating the statistics : {}", e.getMessage()); LOGGER.debug("Details : ", e); throw e; } }
其中:
writeIntervalCsvData(intervalStatistics);writeIntervalSummaryData(intervalStatistics, lastCall);
分别将采样数据写到output.csv和*.data。
注意,有2个check方法:
checkTooLowTps(getTpsValues());checkTooManyError(cumulativeStatistics);
checkTooLowTps(getTpsValues());
会判断1分钟内TPS小于0.01,如果为true,将向ConsoleShutdownListener监听器发送停止信号。
/** * Check if the TPS is too low. the TPS is lower than 0.001 for 1 minutes, * It emits a shutdown event to the {@link ConsoleShutdownListener} * * @param tps * current TPS */ private void checkTooLowTps(double tps) { // If the tps is too low, which means the agents or scripts went wrong. if (tps < 0.001) { if (momentWhenTpsBeganToHaveVerySmall == 0) { momentWhenTpsBeganToHaveVerySmall = System.currentTimeMillis(); } else if (new Date().getTime() - momentWhenTpsBeganToHaveVerySmall >= TOO_LOW_TPS_TIME) { LOGGER.warn( "Stop the test because its tps is less than 0.001 for more than {} minitue.", TOO_LOW_TPS_TIME / 60000); getListeners().apply(new Informer<ConsoleShutdownListener>() { public void inform(ConsoleShutdownListener listener) { listener.readyToStop(StopReason.TOO_LOW_TPS); } }); momentWhenTpsBeganToHaveVerySmall = 0; } } else { momentWhenTpsBeganToHaveVerySmall = 0; } }
private void checkTooManyError(StatisticsSet cumulativeStatistics)
:会判断10s内事务数错误率>=50%,如果为true,通知监听器ConsoleShutdownListener listener终止任务。
/** * Check if too many error has been occurred. If the half of total * transaction is error for the last 10 secs. It notifies the * {@link ConsoleShutdownListener} * * @param cumulativeStatistics * accumulated Statistics */ private void checkTooManyError(StatisticsSet cumulativeStatistics) { StatisticsIndexMap statisticsIndexMap = getStatisticsIndexMap(); long testSum = cumulativeStatistics.getCount(statisticsIndexMap .getLongSampleIndex("timedTests")); long errors = cumulativeStatistics.getValue(statisticsIndexMap .getLongIndex("errors")); // testSum 成功事务数, errors 失败事务数 // hugang if (((double) (testSum + errors)) / 2 < errors) { if (lastMomentWhenErrorsMoreThanHalfOfTotalTPSValue == 0) { lastMomentWhenErrorsMoreThanHalfOfTotalTPSValue = System .currentTimeMillis(); } else if (isOverLowTpsThreshold()) { LOGGER.warn( "Stop the test because the count of test error is more than" + " half of total tps for last {} seconds.", TOO_MANY_ERROR_TIME / 1000); getListeners().apply(new Informer<ConsoleShutdownListener>() { public void inform(ConsoleShutdownListener listener) { listener.readyToStop(StopReason.TOO_MANY_ERRORS); } }); lastMomentWhenErrorsMoreThanHalfOfTotalTPSValue = 0; } } }
3.总结
nGrinder中断测试任务,是一种保护机制,当被测系统性能已经很差,nGrinder不会继续对该系统产生压力。
判断标准:
- TPS在1分钟内小于0.001
- 事务错误率在10s内大于等于50%
如果上述条件,某一条为true,自动中断任务。
附:
nGrinder的debug日志为: /root/.ngrinder/logs/ngrinder.log
0 0
- nGrinder源码分析:自动中断测试任务
- nGrinder对监控机器收集自定义数据及源码分析
- nGrinder源码分析:详细报告页数据展示
- Web压力测试工具nGrinder
- 【性能测试】nGrinder设置hosts
- 解决nGrinder僵死任务的方案
- linux中断源码分析 - 软中断(四)
- linux中断源码分析 - 中断发生(三)
- linux中断源码分析 - 软中断(四)
- linux 内核中断源码分析
- 分析linux中断源码初始化
- nGrinder工具进行接口性能测试
- jstorm源码分析:任务领取
- OkHttp3源码分析[任务队列]
- OkHttp3源码分析[任务队列]
- Spring定时任务源码分析
- linux中断源码分析 - 软中断(四)中断源码分析 - 初始化(二)
- 性能测试之工具对比-ngrinder jmeter loadunner及ngrinder安装使用方法
- java中的重写---在笔试中重新认识其特性
- C++第一次上机实验报告—02
- 简单的调用本地服务器播放网络视频
- lsb_release -a 查询系统版本
- mac下maven的安装和常用命令
- nGrinder源码分析:自动中断测试任务
- static作用
- 百度地图导航没有声音
- 总结以下三种方法,实现c#每隔一段时间执行代码:
- 人工智能随想
- selenium(2)
- oracle SELECT INTO 和 INSERT INTO SELECT 两种表复制语句详解
- 前m大的数HDU 1280(以和为下标比大小)输出M个最大和
- VS2010中,无法嵌入互操作类型