zoukankan      html  css  js  c++  java
  • DCS_FunTester分布式压测框架更新(三)

    经过了两次更新,DCS_FunTester框架的基础功能已经接近尾声了,目前的状态基本能够使用,所以近期不会再进行功能更新了。

    Gradle多模块

    由于之前一直写成了两个项目masterslave,考虑到这样使用多有不便,所以写到了一个Gradle项目里面了。算是个小小地更新。也踩了踩Gradle多模块项目的坑。

    这里有几个坑,可以给大家分享一下:

    依赖另外模块

    经过一顿乱操作,我找到了一种实现方式:

    dependencies {
        implementation project(':slave')
    }
    

    在网上搜了好几个教程都不管用,阴差阴错中我得到这个正确的解。而且在根目录下的build.gradle文件中取消了设置项目子模块的设置,我也没懂到底Gradle设置多模块的模板是什么样子的,算是积累成功经验吧。

    最近在使用Maven作为构建工具开发新版的DCS_FunTester感觉效果不错,感觉现在Maven比两年前好用多了,特别是配合Intellij使用的时候。

    子模块依赖

    我搜到的资料将可以在父类模块的build.gradle中配置子模块依赖,试过几次,其中都是使用以下方式:

    subprojects{
     dependencies{
        ……万千依赖……
     }
    }
    

    但是始终无法成功,我猜想可能我在子模块中用到compile或者说是依赖了本地的jar包,哪位大佬有知道的可以指点一二。

    setting.gradle

    这个比较简单,大多数教程讲的都是对的。

    rootProject.name = 'dcs_funtester'
    include 'slave'
    include 'master'
    

    结果收集

    对于测试结果处理,我现在的思路就是汇总到master节点,然后统一由master节点管理,无论是入库也好、合并计算也好。

    这里在slave节点执行用例的结束的时候,会把结果同步到master节点。

    下面执行单个请求时候的Demo:

        @Async
        @Override
        public void runRequest(HttpRequest request) {
            BaseRequest r = request.getRequest();
            HttpRequestBase re = FunRequest.initFromJson(r.toJson()).getRequest();
            Integer times = request.getTimes();
            String mode = request.getMode();
            Integer thread = request.getThread();
            Integer runup = request.getRunup();
            String desc = request.getDesc();
            if (mode.equalsIgnoreCase("ftt")) {
                Constant.RUNUP_TIME = runup;
                RequestThreadTimes task = new RequestThreadTimes(re, times);
                Concurrent concurrent = new Concurrent(task, thread, desc);
                PerformanceResultBean resultBean = concurrent.start();
                SlaveManager.updateResult(resultBean, request.getMark());
            }
        }
    

    对应master节点的接口controller代码如下:

        @ApiOperation(value = "更新测试结果")
        @ApiImplicitParam(name = "bean", value = "测试结果对象", dataTypeClass = PerformanceResultBean.class)
        @PostMapping(value = "/upresult/{mark}")
        public Result updateResult(@PathVariable(value = "mark") int mark, @RequestBody PerformanceResultBean bean) {
            NodeData.addResult(mark, bean)
            Result.success()
        }
    

    service伪代码,这里我直接放在了JVM里面,没有持久化入库,因为这个功能可能在未来会被抛弃,使用服务端统计来代替压力机统计结果。

        /**
         * 添加运行信息
         *
         * @param bean
         */
        public static void addResult(int mark, PerformanceResultBean bean) {
            synchronized (results) {
                results.computeIfAbsent(mark, f -> new ArrayList<PerformanceResultBean>());
                results.get(mark).add(bean);
            }
        }
    

    任务分发

    思路:当master节点收到任务之后,首先对比任务信息中对节点的需求和当前可使用节点数量。如果足够,获取相应节点,向节点发送执行任务,当所有节点都接受成功之后,返回成功。如果其中失败的,那么回滚已经开始执行的节点,返回失败。

    这里分享一个执行单接口请求的Demo:

        @Override
        int runRequest(HttpRequest request) {
            def num = request.getMark()
            def hosts = NodeData.getRunHost(num)
            def mark = SourceCode.getMark()
            request.setMark(mark)
            try {
                hosts.each {
                    def re = MasterManager.runRequest(it, request)
                    if (!re) FailException.fail()
                    NodeData.addTask(it, mark)
                }
            } catch (FailException e) {
                hosts.each {f -> MasterManager.stop(f)}
                FailException.fail("多节点执行失败!")
            }
            mark
        }
    

    探活接口

    为了更好地管理slave节点的状态,本次更新增加了slave节点的探活接口。由master节点定时去探活,而不仅仅依靠slave节点上报,这个接口作为临时接口,保障了在slave节点频繁上下线导致master节点出现故障。

    后期这个功能也会下线,因为我计划使用nacos对用例状态进行维护,这个也是听从大佬的建议,使用优秀的管理组件,能够节省大量时间和提升可靠性。

    slave节点探活接口:

        @ApiOperation(value = "节点状态,是否存活")
        @GetMapping(value = "/alive")
        public Result alive() {
            return Result.success();
        }
    
    

    master节点实现方式:

        /**
         * 节点是否存活
         * @param host
         * @return
         */
        static boolean alive(String host) {
            try {
                String url = SlaveApi.ALIVE;
                return isRight(getGetResponse(host, url, null))
            } catch (Exception e) {
                logger.warn("节点: {}探活失败!", host)
                return false
            }
        }
    
    

    优化注册机制

    这个和上面探活有所关联,防止在slave节点可以访问master节点,但是反过来无法访问的情况下,master节点出现无效的slave节点情况,这里在slave节点注册时候,增加了探活步骤。

    controller代码如下:

        @ApiOperation(value = "注册接口")
        @PostMapping(value = "/register")
        public Result register(@Valid @RequestBody RegisterBean bean) {
            def url = bean.getUrl()
            def stop = MasterManager.alive(url)
            if (!stop) FailException.fail("注册失败!")
            NodeData.register(url, false)
            Result.success()
        }
    
    
    • DCS_FunTester开发告一段落,基本的功能都已具备,下一步是结合管理组件,实现更好的管理。还有就是结合业务开发响应的功能。最近也在学习nacos

    道阻且艰,任重道远。

    Have Fun ~ Tester !

  • 相关阅读:
    io学习
    asp.net文件上传进度条研究
    asp.net页面中的Console.WriteLine结果如何查看
    谨慎跟随初始目的不被关联问题带偏
    android 按钮特效 波纹 Android button effects ripple
    安卓工作室 日志设置
    安卓工作室 文件浏览器 android studio File browser
    一个新的Android Studio 2.3.3可以在稳定的频道中使用。A new Android Studio 2.3.3 is available in the stable channel.
    新巴巴运动网上商城 项目 快速搭建 教程 The new babar sports online mall project quickly builds a tutorial
    码云,git使用 教程-便签
  • 原文地址:https://www.cnblogs.com/FunTester/p/15165049.html
Copyright © 2011-2022 走看看