写点什么

线程同步类 CyclicBarrier 在性能测试集合点应用

用户头像
FunTester
关注
发布于: 1 小时前

在之前的性能测试方案设计中,如果是涉及到多用户的,我一般都是通过先登录用户,然后再将Base对象传入多线程任务类,以此进行性能测试。


但是这种处理方式有个问题,就是在执行多线程任务类之前,可能会造成等待时间过多,因为需要串行登录用户,如果线程过多的话,等待的时间会稍等长一点。


为此我找到了一个解决办法,就是使用线程同步类CyclicBarrier将用户登录过程在多线程中实现,然后所有用户登录完成之后再进行性能测试方法的执行,简单讲就是设置一个多线程集合点,所有线程都到达集合点之后,再一起执行具体的测试方法。


之前的文章又介绍过多线程同步类CountDownLatchCyclicBarrierPhaser,以及在我之前的性能测试过程中的应用,文章列表如下:


需求

分两步:第一步记录一条数据(有唯一性验证);第二步更改该条记录的状态。


描述比较模糊,简单理解就是insert之后update,业务功能简单。

用例设计思路

虽然业务简单,但是实现比较麻烦,所以我采取了链路性能测试,确定唯一性标记,然后进行update,避免了,单独测试造数据太麻烦的问题。


伪代码如下:


@Override        protected void doing() {            String orderNum = "FunTester" + getMark() + StringUtil.getString(10)            threadmark += orderNum            order.insert(orderNum)            order.update(orderNum)        }
复制代码


这里将orderNum当做标记对象了,用于链路追踪和日志查询。

多线程类实现

我继续采取ThreadLimitTimesCount<Integer>类作为模型类的内部静态类实现,定长线程和固定次数。



private static class FunTester extends ThreadLimitTimesCount<Integer> {
Order order
CyclicBarrier cyclicBarrier
FunTester(int u, int times, CyclicBarrier cyclicBarrier) { super(u, times, null) this.cyclicBarrier = cyclicBarrier }
@Override void before() { super.before() this.order = new Order(getBase(t)) cyclicBarrier.await() }
@Override protected void doing() { String orderNum = "f" + getMark() + StringUtil.getString(5) threadmark += orderNum order.create(101, "FunTester测试课程", 13120454219, 10, 10, orderNum) order.refund(orderNum) }
}
复制代码


这里用到了cyclicBarrier.await()方法,使得所有线程达到该集合点之后,才进行下一步的代码执行。

测试脚本

static void main(String[] args) {
Common.notPrintResponse() ClientManage.init(10, 5, 0, EMPTY, 0) def argsUtil = new ArgsUtil(args) def thread = argsUtil.getIntOrdefault(0, 10) def times = argsUtil.getIntOrdefault(1, 10) def threads = [] CyclicBarrier cyclicBarrier = new CyclicBarrier(thread, new Runnable() {
@Override void run() { logger.info("所有账号登录完成!,即将开始测试!") } }) thread.times { threads << new FunTester(it, times, cyclicBarrier) }
new Concurrent(threads, "一个不可描述的用例场景").start()

FunLibrary.testOver()
}
复制代码


Common.notPrintResponse()方法为了屏蔽测试过程中,打印响应结果,因为日志太多了,处理起来比较麻烦。最近在研究链路测试中对各个接口的数据处理,所以想到了这个方法。

控制台输出

INFO-> 当前用户:fv,IP:10.60.193.37,工作目录:/Users/fv/Documents/workspace/qa/,系统编码格式:UTF-8,系统Mac OS X版本:10.16INFO-> 本校共有:627名老师,852名学生,11个班级!INFO-> 请求uri:不可描述的地址/login,耗时:458 ms, requestId:Fun20210310111251QvElINFO-> 请求uri:不可描述的地址/login,耗时:458 ms, requestId:Fun20210310111251xQKMINFO-> 用户:82951571527,登录成功!INFO-> 用户:82951571522,登录成功!INFO-> 请求uri:不可描述的地址/login,耗时:458 ms, requestId:Fun20210310111251TLmlINFO-> 用户:82951571529,登录成功!INFO-> 请求uri:不可描述的地址/login,耗时:471 ms, requestId:Fun20210310111251CgTdINFO-> 用户:82951571531,登录成功!INFO-> 请求uri:不可描述的地址/login,耗时:483 ms, requestId:Fun20210310111251YQyQINFO-> 请求uri:不可描述的地址/login,耗时:459 ms, requestId:Fun20210310111251IGUsINFO-> 请求uri:不可描述的地址/login,耗时:458 ms, requestId:Fun20210310111251NZQtINFO-> 请求uri:不可描述的地址/login,耗时:484 ms, requestId:Fun20210310111251KVRPINFO-> 用户:82951571525,登录成功!INFO-> 用户:82951571513,登录成功!INFO-> 用户:82951571514,登录成功!INFO-> 用户:82951571516,登录成功!INFO-> 请求uri:不可描述的地址/login,耗时:604 ms, requestId:Fun20210310111251AXdVINFO-> 用户:82951571518,登录成功!INFO-> 请求uri:不可描述的地址/login,耗时:610 ms, requestId:Fun20210310111251KUMmINFO-> 用户:82951571524,登录成功!INFO-> 所有账号登录完成!,即将开始测试!
*********中间省略N次请求日志*************
INFO-> 线程:一个不可描述的用例场景2,执行次数:10,错误次数: 0,总耗时:2.317 sINFO-> 一个不可描述的用例场景进度:▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍ 100%INFO-> 总计10个线程,共用时:3.132 s,执行总数:100,错误数:0,失败数:0INFO-> 数据保存成功!文件名:/Users/fv/Documents/workspace/qa/long/data/易视腾3.3购买退款101112_10INFO-> ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~> {> ① . "rt":210,> ① . "total":100,> ① . "qps":47.619,> ① . "failRate":0.0,> ① . "threads":10,> ① . "startTime":"2021-03-10 11:12:51",> ① . "endTime":"2021-03-10 11:12:54",> ① . "errorRate":0.0,> ① . "executeTotal":100,> ① . "mark":"一个不可描述的用例场景101112",> ① . "table":"eJwBHQDi/+aVsOaNrumHj+WkquWwkSzml6Dms5Xnu5jlm74hMCkTtQ=="> }~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~INFO-> 数据量太少,无法绘图!
复制代码


最后因为测试请求,数据量太少了,所以屏蔽了画图功能,欲知图像如何,请参考:性能测试中图形化输出测试数据



FunTester腾讯云社区钦定年度作者,非著名测试开发 er,欢迎关注。


发布于: 1 小时前阅读数: 2
用户头像

FunTester

关注

公众号:FunTester,650+原创,欢迎关注 2020.10.20 加入

Have Fun,Tester! 公众号FunTester,坚持原创文章的测试人。 FunTester测试框架作者,DCS_FunTester分布式性能测试框架作者。

评论

发布
暂无评论
线程同步类CyclicBarrier在性能测试集合点应用