00:00
哈喽,大家好,然后之前是给大家分享了一下性能测试框架啊鸡类的一些呃代码,还有那个执行类的代码,然后今天给大家分享一下就是两种呃压测模式的实现类的,然后嗯这两种压测模式呢,就是由呃第一种就是这种呃时间限制的啊,就是说我每个任务执行多长时间啊,每个任务就每个县程嘛啊100个线程,每个县程执行一分钟两分钟这样的,然后还有一个是那个呃次数限制的,就这个呃我每个线程执行多少次这样的,呃在实际啊工作中这个执行时间这个啊这个可能用的呃相对于用的使用的场景的话,会比这个次数要多一些,但是呃时间在呃对于某一些业务处理的时候,嗯不如这个次数方便啊,所以我。
01:00
呃,用次数的话,我个人用次数会比较多一点啊,然后这个时间的话啊,会比较少一点啊,是这样的啊原原因就是因为这个次数它可能呃相比较这个呃时间来说,时间限制的来说,它的误差就理论误差会稍微大一点,所以说在做次数的时候啊,在条件允许的情况下,就可以多进行啊更多的次数,如果是每个线程100次不够的话,你可以让他跑200次,这样的话可以呃消耗掉那个一些误,呃消耗掉一些理论的误差啊这样嗯,然后我们开始从这个呃时间啊,限制时间的这个开始给大家分享啊看第一行这个比较简单,第二行就是我用来存每次循环,每次执行的时候都会有一个标记,呃当前循环的,当前的多线程任务呢,每次循环就有一个标记啊,比如说我们现在用的。
02:00
ID啊,这就是我上期讲过的一个全局的开关啊,这个主要的作用就在于啊,如果是在呃把性能放到一个服务端,或者说是一个呃,呃长时间持久性运行的这么一个呃场景下去用的话,我们就需要一个这样的一个K,然后而且这个K还可以用来做一些别的呃,比如说呃可以控制一下那个全局的那个任务数就可,呃当前运行的多线程任务数是这样,但是呃暂时还没有做,因为是那个那个时候这个地方其实应该就可以加上那个同步符号,但这里没有这个,这个地方就主要就是呃控制一下全呃,如果我比如说我压测了,呃压测设设定了十分钟的话,或者设设那100次执行,刚执行完就啪啪啪的报错,其实那我们就没有。
03:00
要再执行下去了,然后我们就可以通过一个调这个方法去所有的都下来,然后这个执行的时间啊,任务执行的时间啊,看就是我执行多少秒啊,这个这些构造方法啊,这里我建议一下,就是我两个时间内的构造方法都是有一呃有两个,一个是空参的,一个是三个参数的啊不同的是这个是时间啊,另外一个是times,呃次数,还有一个mark对象。玛卡的标记对象啊,完了之后呢啊,我建议也是大家用一个,因为呃参数比较多,呃构造方法比较多的话,用起来会很乱啊,一乱容易出错啊,出错的话啊,越是复杂的呃业务或者复杂的测试的话,呃出错的话排查成本会比较高,所以说啊,我也是经过一些实践吧,就确定就只用所有的实现类,就只用一个构造可用的构造方法,这个空仓的就呃就无所谓了啊,这是一个run方法啊,Run方法会比较多,然后我们待会再呃讲这个乱方法啊,先讲下面几个不太重要的啊,Stop,这个就是把这个K设成错,然后呃这个软方法里面会有一个判断,然后就可以实现停掉所有的,因为这个K是那个静态,然后这个状态就是说呃,我这里是通用的定义了一个就是每个呃,多线程的任务的话,它。
04:31
每一次执行呃都会有可能会出错,然后每一次循环出错一次,我记一次l number完了之后直如果这个l number大于十的话,我就当前这个任失啊这个是一个就是我们我们自己一个规定吧,和自己写的时候己一个规定,然后大家可以设可以自己改了,然后这个before的话,就把可设成呃设为设置成它的默认值,然后在after呢,After会比较简单,先先是掉了一个super after super after里面就是呃处理一下这个,看到这个对象,然它减一提入进选一,然后这里面max就等于你又就重新呃把这个max清零,然后这个是这个为什么要清零呢?因为呃在如果我是一个是能监控的一个这么一个程序长时间运行的话,我不可能每一次都去创建任务对象,呃,所以说我就创建完一次任务对象。
05:31
款之后,我这个对象我可能会呃多次执行,那这样的话,在多次执行的时候,呃这个每执行一次就要把这个max max是记录那个标记,一个标记,就是把这个标记啊全都清空掉,这样的,然后这个GC呃的这个GC线程的话,它这个它这个主要功能就是用来回收那个之前给大家讲过呃呃关闭超时的连接,还有那个呃关闭空闲的连接啊是这样的这样的,然后如但是是因为我们这儿呃压测的话,主要是ATP居多啊,这double还有其他协议的呃比较少啊,所以说我就直接在这个方法,呃这个把这个GC stop这个方法写在这里面了。
06:20
直接写在这个after里面了啊这个。呃是嗯,就是个人的一个,就写在里面比较方便,而且它stop的话影响也不大,大家看一下就是stop了,就把它flag改成for就可以了。完了就就没了,然后不涉及那个G。啊,进行这个开始。大家看一下这个。这个就是阴逆的话,然后就是哎,这就是一个现成,这是一个方法,然后没有睡的,没有睡了之后,他在这就会有一个错吧,然后这个是stop的话,其实是不影响,然后呢,我们去看一下这个让方法里面写的东西,让方法呢,就首先啊执行了一下比before,然后新建一个list史,呃,我用来记录每一次牌的时间,然后记录一个开始的时间,嗯,然后新建一个呃结束的时间,然后这是一个well处,然后这里面大家看我用了很多track catch啊,这为了是统计错误率的,然后呃,经过实践表明呢,嗯,Track开在正常情况下不报错的情况下,它的性能影响非常非常小啊。但是如果报错的话,影。
07:47
性能影响就是比较大的,呃有可能就是呃上百毫秒的这个样子啊,所以说嗯,如果你在呃那有呃我们这儿一般就是要求不报,绝对不报错,报错的话就表明这个用力已经失败了啊,性能测试也有用力失败的情况啊,这样的就是如果报错的话,就可以认为这个用就失败,如果是有些比如说有些业务,呃可能啊有些公司的业务,他对这个错误率是呃没有太多的,呃没有一个非常严格的限制的话,大家去测那个呃性能压测的时候,他可能在有一定报错率的情况下,它也会有压测结果在这个框架里面,但是那个呃压测结果是不准的,呃是这样的,大家去呃是不不是太准的,呃大家注意下这个就可以了。
08:39
嗯,然后这是嗯,这是c mark这个string,然后把它给赋值啊赋值的结果呢,就是这个mark如果等于烂的标记对象等于烂的话,然后就呃空格啊空的,然后如果不等于那的就调用它这个mark方法,大家看到这个接口,这个mark方法就是标记这个执行线程的,然后返回一个string,然后记录一下开始时间啊,这是每一次循呃一个多线程内的每一次循环的开始时间,然后对应就是他做的事情啊,发生多也好,或者做什么组合的请求也好,然后这是给这个in time赋值啊这里,然后呃,这个number加加就执行一次,表示执行多了一次,然后呢,这个是那个。
09:39
那个那个那个啥来着,计算一下时间差,然后把这个呃时间差添加到这个list里面,然后哎,这怎么会有个output嘞啊,这可能是我调试的时候写错了,哦对,应该是写错了啊嗯,这里面还有一个就是你刚才应该是我调试的时候多写了,然后这个对等于那个嗯超一个呃可你看可接受的超时时间,呃就是我在那个,比如说我在压测过程中,我每个呃请求只要超过两秒,我就把它记下来,这样的它一旦超过这个时间,然后这个max就可以记录一下就是时间,然后加一个连字符连接符,然后加上这个标记的string,那就可以了,然后这里如果是它这。
10:39
这个时间,呃,你看大家看这个1T啊,就是这个当前的就是循环结束的时间,在这里面过值,它这个时间大于减去这个SS,呃大于这个time的话,呃或者说这个呃是for的话,就因为当前任务已经失败了,我就不了,或还有这个就是呃全局的一个K结束的话,我也就不管它了。
11:06
就直接就跳出这个循环就算结束了啊是这样的,嗯,这里面呢。大家看这个呃,如果在这前面的整个过程中啊,发生了异常啊,啊,极大可能就是这发生了异常啊,对咱后面的就是啊,不太可能发生异常的,然后异常之后我就会把这个异常记录下来。然后l number加加啊,这里面有个问题啊,就是在q number,嗯,你给大家看我这个并没有进行对它进行初始化嘛,然后它默认值应该是零,嗯,如果是需嗯嗯最是终统计出来的结果,嗯在在这地方跟这个地方就有可能,如果我这发生了异常之后。我这个l number会加价,但这个q number它不会加价啊,Number只是代表请呃请求成功的一个number啊,它并不代表发送了多少请求,如果发送多少,如果大家想统计发送多少请求的话,就要把这一行移到呃国处这。
12:17
应该移到最上面,这样拆开你这之前这样的啊,然后呢,这个l number就是发请求整个过在这一部分过程中发生异常的次数,然后完了之后,等这个我要处全部结束之后,然后我们会记一个呃那个 time11time,然后一一减去这个SS,然后这是呃那个呃做一个简单的日志,然后这里面就是all the time,就是这个记录所有请求的时间呢,然后添加,把这个T总总的时间添加过去,然后这个request的mark呢,也添加到这个这里面,诶然后这个完事之后,然后调一下阿,是这样的一个逻辑,呃,大家看这地方,其实呃在这个地方的话,呃,它。
13:17
也会有刚才提到那个问题,就是说我这个因为它stay静态的嘛,嗯,然后他也会有那个重复多次运行的时候,然后这里面大家看在O在里面每一次线程结束任务之后,我会把这两个历史清空啊,所以说这个就是在多次运行的时候啊,要注意的事情啊,然后呢,呃,我们这个就是限制时间的这个压测框架就算已经结束了。啊,这个一个模式,然后这个我们只这个里面的东西,软方法里面的东西应该就不用动了,那我们如果是想那什么的,想做测试的话,只需要呃继承一下这个类,然后实现一下doing这个方法就可以了,这样然后呢,我们看一下time啊time的比较简单啊,跟那个一样,因为他这里面处理了,直接就处理了这个time有次数,然后也是唯一的一个可用的构造方法,然后软方法,嗯,先先抛开软方法,我们看后面也是一样的一个stop的,然后这个后面这些也都是一样的,完了之后我们看这个软方板里面的,呃,也是比before,然后新建一下这个拿到一个时间戳,然后这个这个呃,因为是是这样,因为那个。
14:53
嗯,我在这个那个模式下,其实已经规定了每个线运的次数,除非某些情况下,这直接就跳出了啊这个for,这是一个for循环啊,然后呢啊,正常来说呢,Time是等number是等于这个time,然后嗯,在这个地方呢,我就把它写到那个呃的外面啊嗯,没有没有太多原因,因为就是嗯,如果我把它写到外面的话。
15:25
每进行一次放循环,那我就会记记一次啊,不是把它放到那个,其实啊应该是在放在这儿的,放在这儿应该是啊放在这儿嗯会比较好一点啊,是这样这样的,我们每一个H的time就是呃每一次发送或执行每一次循环之后,会把这time加加这样的,这样的话我们就可以统计这个我执行了多呃,执行成功了多少次,就是执行成功的次数,如果是嗯,如果是这个线能跑完的话,应该是time加上这个l time,然后就等于这个time应该会有一个这样的一个啊数值关系,然后这个也是doing应,然后弄完之后加,加完了之后呃计算它的减,呃计算它的。
16:26
呃,就消耗的时间,然后这里面去把添加到这个list里面,然后如果这个大于的可接受的话,然后我们就把这个mark加进去。然后如果是for的话,或者说是还有一个全局的K,然后就break,然后finally,然后就这样,然后这是啊,整个循环结束之后,我记录一下时间窗,完了之后我们去把这个呃,打一下日志,然后添加一下这个。嗯,这个time还有这个呃,Question mark啊这里面啊就是嗯,我刚刚讲过,就是有一个全局的可以执行一次全局的一个K去限制整个GVM里面只有一个多线程任务在跑,但是在这里面啊,在这里面我并没有啊在这个类里面我并没有限制那个嗯,只有一个多线程的对象去往这个all time和requestmark这个添加值啊,如果是大家需要做非常严格的呃限制的话,就是防止就是我嗯很嗯多个任务同时跑起来,呃对执行结果的影响的话,大家还是最好是把这个也也把这个类的呃也做一个全局的K,然后让他呃相当于在同一个界面里面的同一时。
17:59
之间只能存在一个多线程的任务测试这样的,然后这里面是跟那个时间是一样的,然后这里头有一个阿阿掉的也是这些功能啊,是这样的,然后呢,这个这两种压缩模式都已经讲完了,嗯嗯,说一下这个两种压测模式的嗯一些细节吧,就是嗯主要的嗯主要的话差别的我觉得可能是那个呃那个关于呃压测过程中那个结果的计算啊做的啊首先我们知道那个计算的时候是用的嗯线程数嗯去乘以,然后呃单个线程的处理,呃一除以单个线程的平均响应时间,也可以说是全局的平均响应时间啊,然后。
18:59
或者说是用那个呃整个测试执行的总时间来去算呃因为在呃通常情况下,呃一个线程执行的总时间,也就是所有线程执行的总时间,呃那么一个线程执行的总次数,呃总时间除以总次数就是平均响应时间嘛,所以说只有这个替换关系就可以呃把那个呃总的时间和那个平均响应时间给替换过来,但是这里面有一个问题,就是说呃就拿HTTP请求来说,嗯并不是所有的时间都花在发送请求等待响应和呃接收响应这一步,呃因为有可能我们是需要对它的呃响应结果进行呃校验,大家可以在那个那个我之前写过的一个分析点me特呃测试的误差原因的时候啊就写过,就是我们的所有的。
19:59
时间并不等于平呃,拿那个总的时间呃,总的次呃的时间除以总的次数,并不等于我们的请求平均响应时间。因为在不管是在。
20:14
嗯,请求之前还在请求之后去做的任何的呃操作他都会消耗时间,呃,所以说啊,这就是啊减煤上有时候误差会比较大的一个原因之一啊,这里面我用到的啊,计算呢,就是我只算平均响应时间啊,就是你在第一次响应结束到第二次请求发出中间所做的时间,我是不会记,我会记录,但我计算的时候我不会管它,不知道这样说呃能是不是比较好理解一点,就是说这个时间我知道我会记录这个时间,但是我在计算呃,QPS的时候我不会去管它,因为我用的是就是呃N多个从请求开始,呃发送请求到收到响应这中间的间隔是真正的平均响应时间,而不是用最终计算,QPS不是用的总的,嗯。
21:14
线程执行的总时间,所以说这里面就带来一个误差啊,就是说我这个框架里面的一个最重要的,呃,最大的一个误差来源就是在于呃,请求结束之后。就在结,就在这个doing应里面,Doing应里面你如果只是发送请求的话,这个结果还是比较准的,但是如果doing里面你是呃做那个呃,比如说做了一些校验,然后再做一些别的操作,比较耗时的话,那我会把你这个呃时间也算到平均响应时间里面。是这样,然后就会导致我算出来的QPS啊,要实际上是远是比较是低于服务器正常的QPS的啊是这样,所以说如果在使用这个框架的时候,如果你要对测试结果进行验证的话啊,如果只是简单的验证一下结算的扣啊,什么玩意儿的所下这啊这种是耗时非常少的,这个可以就直接可以忽略掉了,呃如果是做呃比较耗时的操作,嗯,你比如说我从接口里拿参数之后,我还需要进行参数的,呃,特别是那些H那做PP项目的,呃,参数加密,参数加密是非常耗时间的,特别是在性能测试的时候,由于本机的呃呃本机的性能不高嘛,然后加密会消耗很多CPU,然后就会导致每一次加密时间会比较长,呃这个时候我有两个建议,一个建议就是,嗯嗯,在这种情况下,如果是在校验,校验过程。
22:50
程中的话,我们可以去异步校验,我们先把结果存下来,然后我们做异步校验啊,这样的啊,如果是这个,呃,这这个耗时操作,没法取消,像我刚才说过的就是参数加密。
23:04
我需要从一个地方拿到参数之后,我加密完之后,再把这个参数有一个加密的签名啊,放到参数里面,然后发给服务器,这里面也会有一个,如果那个呃,你的项目里面这个参数是写死的话,就是说我都可每次请求的参数我都可以预期的话啊,我建议提前把这个参数全都给加密完,加密完之后我们去,嗯,把这些加密的数据先读到GVM里面,完了之后,这样这些参数就发生请求,这样的话误差会比较小啊。还有一个就是呃,跟刚才说的一样,就异步去远整它,我比如说我呃某一个接口,我的验证,验证逻辑非常复杂,可能会比较耗时啊,但是我就先把它想要结果存起来,嗯,把每一个响应结果都存起来,在我项目执行完之后,我再去把每一个响应结果都验证一遍,然后得出。
24:04
一个呃,L number,或者说是一个呃,单独的一个正确率错误率这样的一个数据啊,这是这样啊,这是有两点建议,嗯,OK啊,下一次我们就可以分享一下,呃,关于那个比较简单的啊,就是那个request http request的它的一个实现啊,还有那个一些简单的DEMO尝试啊,今天的分享就到这里了啊,欢迎大家关注公众号,下期再见,拜拜。
我来说两句