基于数理统计分析的服务器端持续性能压力测试方案
作者:石俊娟
摘要:
压力性能测试是软件测试当中非常重要的一部分,也是比较复杂,耗时的一个测试类型。如何提高测试效率,减少人工出错的可能性是本文想要解决的问题。该解决方案利用了数理统计的方法,巧妙的解决了性能测试数据分析的问题,并且提供了一套完整的持续集成方案。
性能测试是服务器端应用软件质量的重要指标。
在我们的项目中,经常需要做性能压力测试以收集性能数据,判断服务器端应用的性能是否维持原有的标准。我们会对应用施以不同的压力,收集不同压力下的各项性能指标,如response time, CPU, memory等数据。测试结束后,我们要把这些数据跟我们的基线进行比较,来得到性能是否有变化的结论。
性能压力测试通常都需要持续一定的时间,另外由于测试数据的波动性,通常要做好几轮的测试。测试结束后,人工的比较数据不仅耗费时间,也容易出错。所以经常一次lnp testing做下来都要至少半天时间。如果发现了问题,还需要troubleshooting,修改了之后继续进行多轮的测试。所以整个周期是比较长的。
在软件迭代如此快速的今天,我们通过把功能测试自动化,已经做到了持续性的测试,可以快速反馈软件的功能问题。那我们是否可以通过自动化整个lnp testing的流程,提高效率,减少人工的差错呢?也就是说,是否能够实现持续性的性能压力测试,尽快反馈软件的性能问题呢?
要实现持续性能压力测试,需要满足三个目标:1)自动获取最新的代码构建,部署应用,并进行压测。2)自动获取压测期间的各项性能数据。3)把收集到的测试数据与性能基线自动地进行比较分析,得出性能是否有变化的结论。
基本的构想是通过Jenkins来构建,部署,触发测试。把测试结果发到一个中央的service,把结果保存到数据库。然后再自动进行数据的比较,再把最后的比较结果通过email发送给用户。
因为数据的波动性,我们没有办法通过绝对值的不同或者某种比例来判断性能的异常,因为这样无法适应不同应用,不同压力下的数据情况。所以我们要找到一种更加科学的方法来进行数据的比较。这里我们就可以利用数据分析,来找到合适的数据模型,然后用数理统计的方法来进行比较。
下面介绍以下具体的实现方式:
1)自动获取最新的代码构建,部署应用,并进行压测。
为了实现自动获取和构建,使用Jenkins的Git插件获取最新的代码,用项目的构建命令来构建应用,然后调用云API把软件包部署到指定的Lnp环境里的服务器上。
利用Jenkins的ParameterizedTrigger Plugin插件来触发另一个做压测的Job。在这个Job中,设置需要测试的压力(TPS-Transactions per second),每个压力测试持续的时间,以及测试次数,基线ID等参数。这个Job将负责完成触发测试,收集数据和比较数据三项任务。
2)自动获取压测期间各项性能数据。
下面我们来看看上一部分提及的测试Job如何实现触发测试,收集数据,分析数据三项任务。
参考上面的架构图,我们可以看到这个CIJob会根据配置的各项压力TPS,时间Duration和jmeter script参数,产生相应的jmeter的脚本,拷贝到一台Jmeter Client机器,在该机器上执行Jmeter的命令来触发压力测试。
Jmeter脚本执行完毕之后,调用命令产生相应的结果文件,再传送回CI Job。CI Job上的脚本会对传回来的结果文件进行解析,然后发送给Lnp Dashboard (名为Clap)。Clap会把发送来的数据存储到数据库。
当各轮测试都结束后,Clap系统负责做数据的比较以及报表的发送。具体的流程图如下:
我们采用Jmeter来触发性能测试,并且收集测试数据。使用Jmeter的Aggregate Report listener来保存这段测试时间内的ResponseTime,使用PerfMon Metrics Collector来保存CPU和内存的使用情况。
3)把收集到的测试数据与性能基线做自动化的比较分析,得出性能是否有变化的结论。
如何进行比较是整套系统的难点。因为性能数据是波动的,并不总是维持在一个固定的值。即使是采取同时对老版本和新版本进行压测,得到的结果也可能是不同的。所以以往我们的比较都是凭经验,靠感觉。”恩,差个5ms,应该问题不大”。对于不同的系统,5ms的差距意义是不同的,对于不同压力下的差别也不同。临时的5ms差距和稳定的5ms差距的意义也是不同的。而百分比的比较也同样不够精确呢。那我们到底怎样进行科学的比较呢?
我们做了实验,持续不断地做压测,收集了大量的数据进行数据分析,企图找到一个比较准确的数据模型。利用数据分析工具分析后,我们发现我们的性能数据近似的符合对数正态分布。那我们就可以利用正态分布的统计方法进行性能数据的比较。
所谓对数正态分布,也就是说这些数据的对数符合正态分布。根据正态分布的经验法则,(μ :平均值,δ:标准差),< μ+3δ的可能性是99.9%,>μ+3δ的可能性只有0.1%。< μ+1.96δ的可能性是95%,为了数据的准确性,我们认为如果数据>μ+1.96δ的可能性只有5%,这是一个相当小的概率。我们可以认为这个数据是Outlier异常值,而把它排除掉。重新计算95%置信区间的数值。当我们找到这些可信的数据后,就可以把这些数据保存成基线。以作为下次比较的基准。
由于在实际操作中,我们测试时采样的数量比较少,所以用少样本容量的正态分布—T分布来计算这个置信区间。
当我们下一次测试时,同样,我们也分批多次测试,取得一系列的测试结果。然后把这些作为样本数据,用T检验来检验这些数据是否与保存的基线均值一致。
T检验,亦称student t检验(Student'st test),主要用于样本含量较小(例如n<30)的正态分布检验。
1、建立虚无假设H0:μ1 = μ2,即先假定两个总体平均数之间没有显著差异;
2、计算统计量t值,对于不同类型的问题选用不同的统计量计算方法;
1)如果要评断一个总体中的小样本平均数与总体平均值之间的差异程度,其统计量t值的计算公式为:
2)如果要评断两组样本平均数之间的差异程度,其统计量t值的计算公式为:
3、根据自由度df=n-1,查t值表,找出规定的t理论值并进行比较。理论值差异的显著水平为0.01级或0.05级。不同自由度的显著水平理论值记为t(df)0.01和t(df)0.05
4、比较计算得到的t值和理论t值,推断发生的概率,依据下表给出的t值与差异显著性关系表作出判断。
我们利用apache的commons.Mathlibrary中的TTest类的tTest方法来帮助我们进行t检验。根据计算的p值,如果p>0.05,我们认为这组数据与基线一致。否则,则认为这组数据与基线不同。
具体的流程图如下:
根据这套算法得出性能变化之后,Clap系统产生出报表,发送到用户的邮箱。
该报表通过不同的颜色和上下箭头来表明性能指标的变化。用户可以一眼看出性能的差异。
总结:
有了这套Clap系统之后,我们就可以每天收到系统发送的报表,快速得知最新代码的性能情况,如果性能出现衰减,可以快速进行修改。大大提高了软件的发布速度和质量。
这个性能比较利用了统计学的方法,这也启发我们交叉学科可以为我们提供更多解决问题的思路。不仅仅可以应用在性能测试,还可以运用到其他需要进行数据比较的测试当中。我们可以进行数据分析,找到合适的数据模型,再利用这种模型的算法来帮助我们进行自动化的处理,这就可以大大提高我们的生产效率。