性能测试误差对比研究(一)

之前思考过两种统计模式的各种误差来源,以及如何避免这些可能产生的误差。又做了一些具体的框架改进,如下列文章所示:

今天分享一下在性能测试统计中,各种参数和性能指数对性能测试误差的影响,以及各种减少误差方法效果,以便知道以后的性能测试改如何改进。

演示Demo

我写了一个模拟正常单接口性能测试的时候的Demo,我使用了ThreadLimitTimesCount<String>模型,使用sleep()方法模拟请求和响应,具体代码如下:


/**
 * 性能测试统计误差测试类
 * by:FunTester
 */
class DeviationTest extends SourceCode {


    static void main(String[] args) {
        def ts = []

        10.times {
            ts << new FunTester(StringUtil.getString(10), 60)
        }

        new Concurrent(ts, "FunTester误差分析").start()

    }

    private static class FunTester extends ThreadLimitTimesCount<String> {


        FunTester(String s, int times) {
            super(s, times, null)
        }

        @Override
        protected void doing() throws Exception {
            sleep(0.1)
        }

        @Override
        ThreadBase clone() {
            new FunTester(StringUtil.getString(10), times)
        }
    }

}

下面开始针对之前提到的误差来源进行对比分析了。

由于模拟的时间比较短,这里就不进行标准的演示了。在我自己测试空转的过程中也很难在ms级别统计代码运行,所以我也放弃了对代码运行时间的对比。

线程数

首先来研究一下,线程数对性能测试误差的影响。首先我们先来一组配置20线程、50请求次数在固定请求时间的情况下的模拟,看一下结果。

~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
>  {
>  ① . "rt":103,
>  ① . "failRate":0.0,
>  ① . "threads":20,
>  ① . "deviation":"3.29%",
>  ① . "errorRate":0.0,
>  ① . "executeTotal":1000,
>  ① . "qps2":187.79342723004694,
>  ① . "total":1000,
>  ① . "qps":194.1747572815534,
>  ① . "startTime":"2021-04-05 15:40:58",
>  ① . "endTime":"2021-04-05 15:41:04",
>  ① . "mark":"FunTester误差分析051540",
>  ① . "table":"eJztjzEKwkAQRfvA3mEOkEC0sMgBPIDkAgEHXHBXySYQSxElpVVKj2BK7xOIeAxX7SzcFUQZmeHDm2r+PBGAx4xLnaIpML+0bX869vXufNjDMIZilmM29TkBIhCvuyZolgttEFKpMIEqMpjLbA66VCGsIoVTmWlXh/sPJTU8biWDOAZlQpVVdh3Z9QMWjumajY0DWxs/1Db2p65Z28AzPKreLr43fhs3w58UsyEbsiEb/hHYkD7YkD7YkD7YkD7YkD7YkD7YkD7YkD7YkD7YkD7YkD7YkD5EcAVmaHb1"
>  }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~

实测平均耗时103ms,总的误差是3.29%,不算很高。下面看一下配置40线程、50请求次数在固定请求时间的情况下的模拟,看一下结果。

~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
>  {
>  ① . "rt":103,
>  ① . "failRate":0.0,
>  ① . "threads":40,
>  ① . "deviation":"2.7%",
>  ① . "errorRate":0.0,
>  ① . "executeTotal":2000,
>  ① . "qps2":377.8575477045154,
>  ① . "total":2000,
>  ① . "qps":388.3495145631068,
>  ① . "startTime":"2021-04-05 15:43:19",
>  ① . "endTime":"2021-04-05 15:43:24",
>  ① . "mark":"FunTester误差分析051543",
>  ① . "table":"eJztz08KgkAUBvC94B3eARQUooUH6ADhBQQHEpopHANbRv9ctnLZEXLZfQSjYzTVrmiUCsbFNzz43Pje97Mt6vBGCxEymbH0WlXN+dQUu8vxQAOPsknKorjLCrItW39rzOR8JiSjMOEsoNyVLE2iKYkFd2jpchYnkWi70d6DJ4KeuwLf84hLh0d54PtD9fkHxa+vLgs1nSS9vFKXKzWfQnf1wy9rNW+xVdMt9mq+iUdTXdhWXW7U0Gvo2rRu7VPchT2oASGEEJqvASGEEJqvASGEEJqvASGEEJqvASGEEJqvASGEEJqvASGEWuENvcRZ6Q=="
>  }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~

实测平均耗时103ms,总的误差是2.7%,可以说很相近,再试一组100线程的,其他条件不变。

~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
>  {
>  ① . "rt":102,
>  ① . "failRate":0.0,
>  ① . "threads":100,
>  ① . "deviation":"3.7%",
>  ① . "errorRate":0.0,
>  ① . "executeTotal":5000,
>  ① . "qps2":944.1087613293051,
>  ① . "total":5000,
>  ① . "qps":980.3921568627451,
>  ① . "startTime":"2021-04-05 15:44:33",
>  ① . "endTime":"2021-04-05 15:44:38",
>  ① . "mark":"FunTester误差分析051544",
>  ① . "table":"eJztzz0KwjAUwPE9kDu8A7RQF4cewANILxAwYMBEaVqoo4jS0amjR7Cj9ylUPIYpblXaih/w5IUHv0x5+XMGA84kNZG0iYyvZVmfT3W+vxwPMAoCSOaxFLMhb3DGu3dNpV0tjZUQKS1DyHwrYyUWYFLtwdrXcqaE6dvR/w+tDNzfCpsAbT0tMncdu+sHKrpOVWzdPLBz8xK5mxacVcXGDbR5urGLt77xRZrC326kQiqkQir8P6gQP1SIHyrEDxXihwrxQ4X4oUL8UCF+qBA/VIgfKsQPFeKHsxsIDnrM"
>  }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~

这次虽然平均响应时间更准了,但误差反而更高了,我们再试一组200线程的。

~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
>  {
>  ① . "rt":103,
>  ① . "failRate":0.0,
>  ① . "threads":200,
>  ① . "deviation":"3.2%",
>  ① . "errorRate":0.0,
>  ① . "executeTotal":10000,
>  ① . "qps2":1879.6992481203008,
>  ① . "total":10000,
>  ① . "qps":1941.7475728155339,
>  ① . "startTime":"2021-04-05 15:45:27",
>  ① . "endTime":"2021-04-05 15:45:33",
>  ① . "mark":"FunTester误差分析051545",
>  ① . "table":"eJztjz0KwkAQRvvA3mEOkEC0MwfwAJILBFww4K6STUBLxZ+UVik9gpbeR4h4DEctRDBmQVFGZ/ngTbPzzRMOWLx2pkNpUpkct9tytynzxWG9gqbvQ9pLZNS12SEc8byrI81woI2EMFYygJFnZBJHfdCZcmHsKdmNI13XUX+HijVcdwUNFFDGVdEIxxaOb7B49e2LHGNlcvsywdRghqnCHGOHy233EM6+mGKgAvbLl5gqPCj+GM6G3+xnQzZkQzb8BbAhfbAhfbAhfbAhfbAhfbAhfbAhfbAhfbAhfbAhfbAhffyD4QlUrRlG"
>  }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~

目前来看,线程数对于误差影响不大,几乎可以忽略。

时间&次数

再来看看测试时间和请求次数的影响,因为这次我选择的固定请求次数的模型,所以主要研究参数还是请求次数。

首先来一组,20线程、20请求次数在固定请求耗时的模拟结果。

~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
>  {
>  ① . "rt":105,
>  ① . "failRate":0.0,
>  ① . "threads":20,
>  ① . "deviation":"5.28%",
>  ① . "errorRate":0.0,
>  ① . "executeTotal":400,
>  ① . "qps2":180.42399639152006,
>  ① . "total":400,
>  ① . "qps":190.47619047619048,
>  ① . "startTime":"2021-04-05 15:48:19",
>  ① . "endTime":"2021-04-05 15:48:21",
>  ① . "mark":"FunTester误差分析051548",
>  ① . "table":"eJztkksKwjAYhPdC7/AfwEIrrnoADyC9QKEBAyZKU0GX4nPpqkuPoEvvU6h4DOMDQbDaWjFdzM/AZDUzH8RqUIHrjKTPVMyi036fHXbZenncbqjlUNyLWBAWiSCrYb3v6jI1HEjFyOeCeTS2FYt40Cc5Ek2a2IKFPJCfOj7vEFzSLctzHYeEaopg7Lntln7+gKLqpclaqxDJ9xULrf80XSvQhKavmtJkqpVnM608u//w0rbSyrPn5Wky16KHlY57kVonuxDWYAYIQQhC8zNACEIQmp8BQhCC0PwMEIIQhOZngBCEIDQ/A4SVCM8WpxSi"
>  }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~

平均响应时间105ms,误差5.28%。现在将请求次数增加到50

~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
>  {
>  ① . "rt":104,
>  ① . "failRate":0.0,
>  ① . "threads":20,
>  ① . "deviation":"2.79%",
>  ① . "errorRate":0.0,
>  ① . "executeTotal":1000,
>  ① . "qps2":186.9508319312021,
>  ① . "total":1000,
>  ① . "qps":192.30769230769232,
>  ① . "startTime":"2021-04-05 15:49:42",
>  ① . "endTime":"2021-04-05 15:49:48",
>  ① . "mark":"FunTester误差分析051549",
>  ① . "table":"eJztz0sKwjAUBdB5oXt4C1BoxVEX4ALEDQQaMGCiNBbqUPx16MihS9Ch+xEUl2HUgeAvhRZi4YYHN4M27x7fowKnk6oe12OeXPb702F3ypfn7ZpaAY37CWdxkSfI9/zfu7pcj4ZKc+oJySPKmpongg1IpbJBk6bksWDKtsPeQwpFj7eiMAhI6oZkWRS2Q3OtQFH2HDe5mUISbMGWum05bqZm3mJmxhJzM5ZYmKks7uU/hu+9frsy84zvf9YlbsI/qAEhhBC6rwEhhBC6rwEhhBC6rwEhhBC6rwEhhBC6rwFhKeEVVbcQ1Q=="
>  }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~

平均响应时间和误差都有所下降,现在增加到100请求,看看结果。


~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
>  {
>  ① . "rt":103,
>  ① . "failRate":0.0,
>  ① . "threads":20,
>  ① . "deviation":"1.51%",
>  ① . "errorRate":0.0,
>  ① . "executeTotal":2000,
>  ① . "qps2":191.2411550965768,
>  ① . "total":2000,
>  ① . "qps":194.1747572815534,
>  ① . "startTime":"2021-04-05 15:50:56",
>  ① . "endTime":"2021-04-05 15:51:06",
>  ① . "mark":"FunTester误差分析051550",
>  ① . "table":"eJztzzEKwjAUBuC9kDu8A7RQHRx6AA8gvUDAgAETpWmhjiJKR6eOHsGO3qdQ8RhG3EqxlQpx+MOD/015/8c8GvDmmY6FSUXyqKrmdm2K0/1ypmlI6SoRfDnkC2Ie+3xrIcx2o42gWCoRUR4YkUi+Jp0pn3aBEkvJdd+N/h5Kanr/FU3CkJTxFc/tOrPrDxTdry4PdnriaOerKOy0gnl1ubdD7Rh5v+OUo3gJ/6AGhBBC6L4GhBBC6L4GhBBC6L4GhBBC6L4GhBBC6L4GhBBC6L4GhBBC6L4GhKOET/9xgkk="
>  }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~

平均响应时间和误差进一步降低了,看来增加请求次数是可以降低误差的,这也是符合直觉的。下面再进行一组200请求次数的测试。

~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
>  {
>  ① . "rt":103,
>  ① . "failRate":0.0,
>  ① . "threads":20,
>  ① . "deviation":"0.69%",
>  ① . "errorRate":0.0,
>  ① . "executeTotal":4000,
>  ① . "qps2":192.8268414963363,
>  ① . "total":4000,
>  ① . "qps":194.1747572815534,
>  ① . "startTime":"2021-04-05 15:52:23",
>  ① . "endTime":"2021-04-05 15:52:44",
>  ① . "mark":"FunTester误差分析051552",
>  ① . "table":"eJztzzEKwjAUBuC9kDu8A7RQHRx6AA8gvUDAgAETpWmhjiJKR6eOHsGO3qdQ8RhGRBBBW7EQhz88+N+U93/Mow5vnOlYmFQkl6pqTsem2J0PexqGlM4SwaddviDmsc+3JsIsF9oIiqUSEeWBEYnkc9KZ8mkVKDGVXLfdaO+hpKb7X9EgDEkZX/HcriO79qB4++pyY6cltna+isLOI5hXl2s79Br9HH4+5Shuwj+oASGEELqvASGEELqvASGEELqvASGEELqvASGEELqvASGEELqvASGEELqvAeFPwisab36D"
>  }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~

相信结论已经很明显了。增加测试请求次数是可以有效降低误差的。

请求耗时

现在模拟一下请求耗时对误差的影响,直觉来讲,耗时越长,误差越小,因为系统误差一定的情况下,耗时越长,误差的所占的比例也就越小了。

先进行一组耗时50ms的测试,线程数20,请求次数设置100


~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
>  {
>  ① . "rt":52,
>  ① . "failRate":0.0,
>  ① . "threads":20,
>  ① . "deviation":"3.99%",
>  ① . "errorRate":0.0,
>  ① . "executeTotal":2000,
>  ① . "qps2":369.2762186115214,
>  ① . "total":2000,
>  ① . "qps":384.61538461538464,
>  ① . "startTime":"2021-04-05 15:56:36",
>  ① . "endTime":"2021-04-05 15:56:42",
>  ① . "mark":"FunTester误差分析051556",
>  ① . "table":"eJztz08KgkAYBfC94B2+AyhIUAsP0AGiCwgOJDRTOAq27C8uW7nsCLnsPoLRMRpqV6QTSRP05MFzNd/72RZpfMNUjJlMWHwpy/p0rPPd+bCnnkfJJGZBqPME2ZbdfGvE5HwmJKNxxJlPmStZHAVTEil3aOFyFkaBaLuhMYRHgu6P+X2PuHR4kPn9gfrrQvHeVxVrFb3KVfSEDydWKq9qq9JSt7v69bSwKpYqetX9nA/Ltqpio0LN9d1RnQt/YAaEEEJofgaEEEJofgaEEEJofgaEEEJofgaEEEJofgaEEEJofgaEEP658ApAgBUd"
>  }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~

下面增大响应耗时到100ms

~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
>  {
>  ① . "rt":103,
>  ① . "failRate":0.0,
>  ① . "threads":20,
>  ① . "deviation":"1.25%",
>  ① . "errorRate":0.0,
>  ① . "executeTotal":2000,
>  ① . "qps2":191.75455417066155,
>  ① . "total":2000,
>  ① . "qps":194.1747572815534,
>  ① . "startTime":"2021-04-05 15:58:00",
>  ① . "endTime":"2021-04-05 15:58:10",
>  ① . "mark":"FunTester误差分析051558",
>  ① . "table":"eJztzzEKwjAUgOE9kDu8A7RQHRx6AA8gvUCgAQMmStNCHUWUjk4dPYIdvU+h4jGMiOBSW6EoT1548GXKy88Z9DjTzETSpjK5VlVzPjXF/nI8wDiAdJ5IEfd5Ajjj73fNpF0tjZUQKS1DyH0rEyUWYDLtwdrXMlbCdO3o/odWBh5vhaMgAG09LXJ3nbjrABWtpy63bjrYufmIws0Tzupy4wZaGGb/68Zvcy/85X4qpEIqpMJ/gArxQ4X4oUL8UCF+qBA/VIgfKsQPFeKHCvFDhfihQvxQIX44uwGetH51"
>  }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~

误差下降了一半还说,再次说明了直觉是对的。现在继续增加响应耗时到200ms

~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
>  {
>  ① . "rt":203,
>  ① . "failRate":0.0,
>  ① . "threads":20,
>  ① . "deviation":"0.95%",
>  ① . "errorRate":0.0,
>  ① . "executeTotal":2000,
>  ① . "qps2":97.58477677482313,
>  ① . "total":2000,
>  ① . "qps":98.52216748768473,
>  ① . "startTime":"2021-04-05 15:59:25",
>  ① . "endTime":"2021-04-05 15:59:46",
>  ① . "mark":"FunTester误差分析051559",
>  ① . "table":"eJztzzEKwjAUgOE9kDu8A7RQOjj0AB5AeoFAHxgwUZoW6iha6ejk6BHs6H2Eiscw4CbW1sHhyQsPvpAhyS8FjFjT0qboCszvbdtdzl2zv50OEEdQzHNU2ZgrQAr5+a0ZutXSOoRUG0ygCh3mWi3AliaAdWgw08oOvTH8D6MtPO9K4igC4wKjKr+d+O2XFdfjxk8fWz997Pz0Ufv5LY2fF6R4e/xHcCF9uJA+XEgfLqQPF9KHC+nDhfThQvpwIX24kD5cSB8upA8X0ocL6cOF9JHiAVtAtsc="
>  }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~

误差继续下降,只不过不是下降趋势不如刚才,基本上也能印证直觉得出的结论是对的,响应耗时越长,误差越小。

响应时间离散系数

实际工作中响应时间都非固定的响应时间,对于某些结果,响应时间可能相差巨大,甚至好几倍的差距。下面我们来看看响应时间的离散程度对性能测试误差的影响。

我引入一个随机的(0,1]的随机数来模拟响应时间的离散系数。

下面是20线程、100请求次数的模拟结果,随机休眠配置是sleep(0.1 + getRandomDouble() / 10),理论平均休眠时间是150ms

~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
>  {
>  ① . "rt":153,
>  ① . "failRate":0.0,
>  ① . "threads":20,
>  ① . "deviation":"3.56%",
>  ① . "errorRate":0.0,
>  ① . "executeTotal":2000,
>  ① . "qps2":126.07160867372667,
>  ① . "total":2000,
>  ① . "qps":130.718954248366,
>  ① . "startTime":"2021-04-05 16:06:34",
>  ① . "endTime":"2021-04-05 16:06:50",
>  ① . "mark":"FunTester误差分析051606",
>  ① . "table":"eJztlU0KgkAYhveCd/gOoGDRygN0gOgCQgMJzRSOQS37d9nKZUfIZfcRjI7RB4EUWJo/afUNL3yzmvd5GH9UBTKs7lT0mXSZcwmC6HSMvO35sIe2Ae7QYdYgyxGgKurrrh6Tk7GQDPo2ZybMdMkc2xqBmHIN5jpnA9sSaR3pHNwWcDvLbBkd4FLj1sxsGwZuS7DIv0J/gcGxweDwMJmM8lTddzyOUhtDf4nBscYk91XSHvc+96yUIvEu844CNKVylEAV+itMJTyF6GKgHaZKrpyU2V+gemkbwfkGdfw8fvbeC9M3njvFouD3uUk23+mQYPT2v/pbhqr8wh2lGTYAgwzJkAzrxyBDMiTD+jHIkAzJsH4MMiTDPze8AjKhbpE="
>  }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~

下面将随机数离散系数增加一倍,配置sleep(0.1 + getRandomDouble() / 5),理论平均休眠时间200ms

~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
>  {
>  ① . "rt":202,
>  ① . "failRate":0.0,
>  ① . "threads":20,
>  ① . "deviation":"5.3%",
>  ① . "errorRate":0.0,
>  ① . "executeTotal":2000,
>  ① . "qps2":93.76465072667604,
>  ① . "total":2000,
>  ① . "qps":99.00990099009901,
>  ① . "startTime":"2021-04-05 16:10:32",
>  ① . "endTime":"2021-04-05 16:10:54",
>  ① . "mark":"FunTester误差分析051610",
>  ① . "table":"eJztlk0KwjAQRvdC7zAHUFAXQnsADyBeoGDAgonSKOjSf5euuvQIdul9CorHcEAUFKmxybQVEgaSVb730gmpUwGF0Z6ILpNjFl7j+Hw6nneby2EPzTqM+yHzeypbgFNx0rM6TI6GQjLoBpx5MK1JFgb+AMSEV2FW46wX+OJbxncOHgi47+U16i3gssr9qdd0XVwasNAaSbTAwmmHpWSTMWaN9YihS0uiJdZbDmFqEs2xPusRpyfRCkslk4RAXZmG4rVxNSc9Gs2jMEr0bMgtllmkzGQ/X5J8CY12Eg1l1rueJ+nzGMk6zyhxbt1oiLrYFtCiL+FRKxso/FCUcHo1oX8TcjX6z0+SavUvN+QXszK9B1SGJcCwhtbQGhaPYQ2toTUsHsMaWsNUwxsm4B0O"
>  }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~

可以看到,误差明显增加了一些,下面再试试配置sleep(0.1 + getRandomDouble() / 2),理论休眠时间350ms

~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
>  {
>  ① . "rt":355,
>  ① . "failRate":0.0,
>  ① . "threads":20,
>  ① . "deviation":"4.85%",
>  ① . "errorRate":0.0,
>  ① . "executeTotal":2000,
>  ① . "qps2":53.60493165371214,
>  ① . "total":2000,
>  ① . "qps":56.33802816901409,
>  ① . "startTime":"2021-04-05 16:13:14",
>  ① . "endTime":"2021-04-05 16:13:51",
>  ① . "mark":"FunTester误差分析051613",
>  ① . "table":"eJztlk1qwzAQhfcB32EOkEASSKE+QA5QcgFDBDFUSrESSJdtfpdZaZkjJMveR5DSY2Sg0EUJthyN5FlYPLBXet+T5GclHXAY46WaCL0Qxc/lcv06Xw+779MRhn1YzAqRTV2mgKSTlHu9CP02V1rAJJcihVVPiyLPXkEtZRfee1JM80xVeVRzyFzB71zpYDAEqbsyW6Wj5yd8JUjhNaz5QOHjgHJKQ2AT1M2aT9Q/q3CO1mxQ9+0CuVqzRZVahnB2t6V1t2aNquFLT+GJQEXicNZi0dQ+DAGJ/splj6JF8iEj3S1auhC7R0VY1t+MSO/+0XjSNruitYlpyjYqdezviYicL3YlPQu8BxOwqA7/JJxqxTMNw8rxSRTt5hEvFfuqeixZwDtr0+lYYLQJ24RtwuYx2oReCW9YS+Wj"
>  }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~

没想到反而有了点下降的趋势,我们再将离散系数增加一倍,配置sleep(0.1 + getRandomDouble()),看一下效果。

~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
>  {
>  ① . "rt":590,
>  ① . "failRate":0.0,
>  ① . "threads":20,
>  ① . "deviation":"10.51%",
>  ① . "errorRate":0.0,
>  ① . "executeTotal":2000,
>  ① . "qps2":30.336584403961957,
>  ① . "total":2000,
>  ① . "qps":33.898305084745765,
>  ① . "startTime":"2021-04-05 16:20:41",
>  ① . "endTime":"2021-04-05 16:21:47",
>  ① . "mark":"FunTester误差分析051620",
>  ① . "table":"eJztl01qwkAYhvdC7vAdQMEfkJID9ADFCwQcMOBMS0bBLv136WqWHkGXvc+ApcfoQKkgtsn8fclEDC8kq3mfh8nMJFEDNK7nKRsQPiHZ1+l0/jied5vPwx66bZiMMpIMdYaAqBHld70Q/vbKOIFBSkkMsxYnWZqMgU1pE95blAzThBV1FGLQlMHPUHGn2wPKmzSZxZ32U189e7BwvaTYqeiYOFRsVdCbpFir/Nagtv1ZhdQoxVwltxKj+VL7fx9WuxQLFYNqvwTG5kgUdvUeKRwRvJA4ToZvIttXE5EKEcmFDB/Lmk6KlUoJaHaEZeNZUGocRpWT6p+bQRBLsVSpmNOMOkBkHfJwsQvpK9oafBkEsRbdLK7/Zepyuza57Ix1VLk1Ku1LozyruqxzQ7OarX8Tu/ubsVvDADAehg/DXMNv5swe1g=="
>  }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~

这下误差增加了不少,我都开始怀疑上一次实验是否是偶然情况下才导致误差并没有升高。不过这个问题跟之后会讲到的同步结束有关联。到时候我修复完异步结束导致的误差增加后,在回过来重复一下离散系数这个实验。

基本结论还是,接口请求响应时间离散系数越大,误差越大。

before & after

下面进行本期最后一个环节,就是beforeafter两个方法中进行耗时操作,对误差产生的影响。其实这里不用进行试验也能得出结论,耗时越长,误差越大。原因就是在请求响应误差一定的情况下,beforeafter执行所消耗的时间,就是增加了总时间T,请求次数相同,总时间T除以总请求次数,QPS肯定是降低的,再加上,QPS=T/count(req)本身就是低QPS计算公式,所以总的结论就是:在beforeafter方法中执行约耗时的操作,误差越大。

下面再before中进行sleep(5)的操作,配置20线程,100请求次数,固定休眠时间100ms

~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
>  {
>  ① . "rt":103,
>  ① . "failRate":0.0,
>  ① . "threads":20,
>  ① . "deviation":"9.82%",
>  ① . "errorRate":0.0,
>  ① . "executeTotal":2000,
>  ① . "qps2":175.1006828926633,
>  ① . "total":2000,
>  ① . "qps":194.1747572815534,
>  ① . "startTime":"2021-04-05 16:32:31",
>  ① . "endTime":"2021-04-05 16:32:43",
>  ① . "mark":"FunTester误差分析051632",
>  ① . "table":"eJztz0sKwjAQgOF9IXeYA7TQuuwBPID0AoUGDJgoTQt167NLV116BLv0PoWKxzA+ltUGtODAhIEvq0l+5oDFGecq4jrj6bWu2/OpLXeX4wFGPmTTlMeJzQpgDvv81oTrxVxpDpGQPITC0zwV8QxULl1YepInIlZ9b/T/QwoFz11h4PsgtSvjIgyC+/UHFd+epirNWJW83bAy08PGjB1bMx2/aqq1GTteKzrZm7Hj8YMhYM6Ay/8CKsQPFeKHCvFDhfihQvxQIX6oED9UiB8qxA8V4ocK8UOF+KFC/FAhfphzAzQA+zM="
>  }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~```

现在讲休眠时间增加到`5s`,再看看结果。


```shell
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
>  {
>  ① . "rt":103,
>  ① . "failRate":0.0,
>  ① . "threads":20,
>  ① . "deviation":"33.29%",
>  ① . "errorRate":0.0,
>  ① . "executeTotal":2000,
>  ① . "qps2":129.5336787564767,
>  ① . "total":2000,
>  ① . "qps":194.1747572815534,
>  ① . "startTime":"2021-04-05 16:33:10",
>  ① . "endTime":"2021-04-05 16:33:25",
>  ① . "mark":"FunTester误差分析051633",
>  ① . "table":"eJztz0EKgkAUgOG9MHd4B1DQVuEBOkB4AaGBBpopHAVbRlQuW7nsCLnsPoLRMRpqE4SOlIseveHB58aZ9zMHepxJpiKuU57cqqq5nJtifz0dYeRDOk94POtzBTCHdb815Xq1VJpDJCQPIfc0T0S8AJVJF9ae5DMRK9sb9j2kUPC8Kwx8H6R2ZZyHQTA2nwNUfHvqsjDTq+SfXqnLjRkLWzNvPFbo2KTlty52ZiwczLTxutGnMGeYe34XKsQPFeKHCvFDhfihQvxQIX6oED9UiB8qxA8V4ocK8UOF+KFC/DDnDnuZ/C4="
>  }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~

结论符合理论值,就不进行更多验证了。

下期将分享一下,异常处理正则异步结束加锁资源等因素对误差的影响,欢迎持续关注。本来打算录视频演示的。可惜时间不是很多,没法准备,以后有机会开个直播聊。


FunTester腾讯云年度作者Boss直聘签约作者GDevOps官方合作媒体,非著名测试开发。