欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于Jmeter后端监听器统计TPS的坑

程序员文章站 2022-07-08 13:10:04
...

      关于Jmeter后端监听器的在使用过程中,确实遇到了不少坑,接上一篇文章《关于Jmeter后端监听器的一个坑》,我们今天再说说关于TPS(Throughput)统计方面的一个坑:

      Jmeter性能测试过程中我们统计的TPS其实就是吞吐率 Throughput(Req/sec),也叫每秒请求数或每秒事务数,而Jmeter后端监听器(BackendListener)在这方面的采样也比较简单,就是汇总包括AllCount、SuccessesCount、FailuresCount的指标,我们将监听器采集的数据查询出来就能看到相关的统计数值,包括all(Total)、ok(Successes)、ko(Failures)的请求数统计值,这和一般汇聚报告或监听器所采集的内容是一样的:

关于Jmeter后端监听器统计TPS的坑

看相关Jmeter源码也能找到对应的采样方法:

   /**
     * Add request metrics to metrics manager.
     * 
     * @param metric
     *            {@link SamplerMetric}
     */
    private void addMetrics(String transaction, SamplerMetric metric) {
        // FOR ALL STATUS
        addMetric(transaction, metric.getTotal(), metric.getSentBytes(), metric.getReceivedBytes(), TAG_ALL, metric.getAllMean(), metric.getAllMinTime(),
                metric.getAllMaxTime(), allPercentiles.values(), metric::getAllPercentile);
        // FOR OK STATUS
        addMetric(transaction, metric.getSuccesses(), null, null, TAG_OK, metric.getOkMean(), metric.getOkMinTime(),
                metric.getOkMaxTime(), okPercentiles.values(), metric::getOkPercentile);
        // FOR KO STATUS
        addMetric(transaction, metric.getFailures(), null, null, TAG_KO, metric.getKoMean(), metric.getKoMinTime(),
                metric.getKoMaxTime(), koPercentiles.values(), metric::getKoPercentile);

        metric.getErrors().forEach((error, count) -> addErrorMetric(transaction, error.getResponseCode(),
                    error.getResponseMessage(), count));
    }

我们从grafana官网下个Jmeter视图模板,也能看到TPS的统计方式很简单,就是获取所有请求的count值(请求数):

关于Jmeter后端监听器统计TPS的坑

1. 查看现象

我们用性能压测平台(https://smooth.blog.csdn.net/article/details/83380879)进行测试实验,其中的echart监控相当于是jmeter的监听器(方法是一样的),我们可以看到其中一个请求的TPS也就在6~7之间,如下:

关于Jmeter后端监听器统计TPS的坑

而通过influxdb-grafana查看同样的请求,看到是在30~35之间,相差了5倍,如下所示:

关于Jmeter后端监听器统计TPS的坑

 我们用html报告,来汇总一下总的TPS趋势图,也能发现相差的幅度处在4~6倍左右:

关于Jmeter后端监听器统计TPS的坑

以上图的时间粒度是1分钟,以下图的时间粒度是10秒,所以平滑度会有区别,但纵轴的数值可以看出差别5倍左右:

关于Jmeter后端监听器统计TPS的坑

 2. 分析原因

       看到这个现象很多小白就已经崩溃了,不知道该相信谁的统计结果,其实细想一下,Jmeter本身的监视应该是相对可靠的,要不然Jmeter也没有存在的价值了。再分析,Grafana的结果也确实离谱,我这都不到30并发线程呢,每秒请求数就达到了几百,这系统速度得快到什么程度。想到这,我们就去找原因,首先Grafana的统计语句是看不出什么毛病,因为Grafana的数据来自于influxdb,问题得先定位采样数据是否有问题,我们只查询一条请求的数据来分析,发现时间是规律的间隔5秒,如下所示:

关于Jmeter后端监听器统计TPS的坑

说明数据的采样频率就是默认的5秒,是不是预感到这块会有坑,我们再来追踪一下Jmeter源代码,发现报告采样调用的请求数是累加统计的,基本上可以理解为这5秒的请求是加出来的,如下代码标示:

关于Jmeter后端监听器统计TPS的坑

问题也差不多找到了,每次监听器采集的count表示的不是每秒请求数,而是每次汇总数,由于间隔5秒,那么每秒请求数应该除以5(这是理论上的,实际肯定会有偏差,但这个偏差可以通过平均数来抹平)。我们重新调整一下grafana的查询语句如下:

关于Jmeter后端监听器统计TPS的坑

或者把原来的语句直接除5处理也行,如下:

关于Jmeter后端监听器统计TPS的坑

 我们再看汇总TPS的图,发现基本上和html汇聚报告里的差别不大了,如下所示:

关于Jmeter后端监听器统计TPS的坑

如果把时间间隔拉长到60s,基本上就和html汇聚报告里的吻合了(采样时间间隔1分钟),(注明:至于图形里最后没有出现降到50以下的点,那是因为测试最后降压太快了,监听器没有采样到最后的点,大部分时段是一致的),如下:

关于Jmeter后端监听器统计TPS的坑

 拿上图Req / sec(每秒请求数)的平均值,再去和html报告里的Transactions/s去比较,差别就没那么大了,如下:

关于Jmeter后端监听器统计TPS的坑

3. 其他问题

(1)首先,大家思考一个问题,Jmeter的请求是包括All、ok(成功的请求)、ko(失败的请求) ,那么我们所说的Transactions/s(TPS)是需要区分ok和ko的请求吗?

(2)再思考一个问题,重定向的请求需要算进TPS吗?目前来看,jmeter的html汇聚报告默认是把重定向请求算进去(因为默认是跟随重定向),而jmeter后端监听器是没有把这部分算进去(这可能算BUG了),结果导致有跟随重定向请求的情况下,两者进行TPS汇总统计会有不一致。

以下是默认勾选了跟随重定向的请求,在html报告里的汇聚统计情况:

关于Jmeter后端监听器统计TPS的坑

关于Jmeter后端监听器统计TPS的坑

 毫无疑问,加了重定向请求的统计,总的TPS肯定会变大不少,所以工具得活学活用,理解的去看,不能死板!

(3)最后,Jmeter的事务控制器要算进TPS吗? 目前来看,默认情况下,html汇聚报告是不包括事务控制器的统计,但是如果在事务控制器上勾选了【Generate parent sample】,那么html报告里是包括事务控制;这一点后端监听器却完全相反,默认情况下后端监听器采集数据就包括了事务控制器,如下:

关于Jmeter后端监听器统计TPS的坑

而在事务控制器中勾选了【Generate parent sample】后,采集到的就只有事务控制器,没有下一级请求数据,如下:

关于Jmeter后端监听器统计TPS的坑

 勾选了【Generate parent sample】,在html汇聚报告里反而是同时有事务控制器和下级请求数据,相当无语,如下:

关于Jmeter后端监听器统计TPS的坑

总之,使用了事务控制器,对两个工具的TPS统计也是会产生影响,导致汇总数据不一致! 这一点上,其他监听器(包括压测平台监听到的)和后端监听器结果是一样的,就是html汇聚报告不一样(总感觉是两个团队做出来的,标准不统一,总之好乱,大家有兴趣的自己可以试试)。事务控制器的配置项如下:

关于Jmeter后端监听器统计TPS的坑

4. 总结

       这次分析,我们明显的发现,本身Jmeter就是个工具,所谓的坑来源于我们自身的理解偏差(“我”是一切问题的根源,这句话我记了十多年),就算是工具有问题,那也是我们可以回避的问题(不踩这坑就行),所以灵活分析和对工具原理的理解才是我们面对一切问题的根本。很多人总是在抱怨这工具问题太多,总是抱怨很多性能指标看不懂,问题是你去深入思考了吗?去思考这些指标和数据背后的东西了吗?另外影响性能统计结果的因素太多了,除了采样频率,性能抖动,统计入口、偏差处理算法等等,以及你的那一点点手抖都会导致统计结果不一样,所以我们能做的就是去抹平这些影响,让测试结果尽量平滑,让采样数据尽量多和丰富,让测试时间尽量拉长,让数据尽量能趋向精确,而不是去纠结工具本身的问题!