zoukankan      html  css  js  c++  java
  • 基于docker的分布式性能测试框架功能验证(二)

    本文是FunTester测试框架分布式性能测试功能拓展实践,是一种比较粗略的技术验证实践,技术方案采用分布式性能测试框架用例方案设想(二)中所设想场景,基于jar包内函数的,这个方案需要将测试用例写到更新到jar包中或者classpath目录下。

    粗实现方案分成三块:master调度机slave测试机server被测服务

    • master调度机:处理用例、分配任务
    • slave测试机:接受任务、执行用例
    • server被测服务:提供测试接口

    docker镜像

    内容同文章基于docker的分布式性能测试框架功能验证(一),这里不再赘述。

    master调度机

    这里我只实现了一种调度功能:就是提供一个接口,该接口返回一个测试用例(尚未封装对象)。提供给slave测试机请求,返回给测试机测试任务(测试用例)。我依然值采用了固定线程固定请求次数的压测模型。

    这里我选择了两种演示Demo:1、将用例写好,暴露执行次数times和执行线程数thread以及软启动时间runup;2、我将待测请求也通过参数化形式放在任务里,用例也只是针对单接口性能测试的一种兼容性拓展。我没有实现更复杂的,因为这个需求我将在方案三种实现,敬请期待。

    这里依然采用了FunTester moco server实现,分布式测试框架单节点版本正在内测,更多消息请留意近期公众号推文。

    master脚本

    这里写了三种不同的返回参数方式,主要是为了匹配测试用例的执行方法,后面介绍测试用例的时候会详细讲解用途。

    package com.mocofun.moco.main
    
    import com.alibaba.fastjson.JSON
    import com.alibaba.fastjson.JSONObject
    import com.funtester.base.bean.Result
    import com.funtester.httpclient.FunLibrary
    import com.funtester.httpclient.FunRequest
    import com.mocofun.moco.MocoServer
    
    class DcsServer2 extends MocoServer {
    
        public static void main(String[] args) {
            def server = getServer(12345)
            def res = new JSONObject()
            res.path = "com.funtester.main.DcsCase.main"
            res.paramsType = ["java.lang.Integer", 10, "java.lang.Integer", 100, "java.lang.Integer", 2]
            def success = Result.success(res)
            output(success.toJson())
            def res2 = new JSONObject()
            res2.path = "com.funtester.main.DcsCase.main"
            res2.paramsType = ["java.lang.Integer", 10, "java.lang.Integer", 100, "java.lang.Integer", 2, "java.lang.String", "http://192.168.80.169:12345/m"]
            def success2 = Result.success(res2)
            def res3 = new JSONObject()
            res3.path = "com.funtester.main.DcsCase.main"
            res.paramsType = ["java.lang.String", "10,100,1"]
            def success3 = Result.success(res3)
            server.get(urlStartsWith("/m")).response(obRes(success))
            server.get(urlStartsWith("/t")).response(obRes(success2))
            server.get(urlStartsWith("/f")).response(obRes(success3))
            def run = run(server)
            waitForKey("fun")
            run.stop()
        }
    }
    
    

    其中http://192.168.80.169:12345/m是被测服务暴露的测试接口,也是用funtester moco server做的,后面也会分享脚本内容。

    测试用例

    其中com.funtester.main.DcsCase.mainjar包中的一个测试用例,类代码如下:

    import com.alibaba.fastjson.JSONObject
    import com.funtester.config.Constant
    import com.funtester.db.mysql.MySqlTest
    import com.funtester.frame.execute.Concurrent
    import com.funtester.frame.thread.RequestThreadTimes
    import com.funtester.httpclient.ClientManage
    import com.funtester.httpclient.FunLibrary
    import com.funtester.utils.ArgsUtil
    import org.apache.http.client.methods.HttpGet
    
    class DcsCase extends FunLibrary{
    
        public static void main(String[] args) {
            ClientManage.init(60, 60, 0, "", 0);
            ArgsUtil util = new ArgsUtil(args);
            int thread = util.getIntOrdefault(0, 2);
            int times = util.getIntOrdefault(1, 10);
            Constant.RUNUP_TIME = util.getIntOrdefault(2, 10);
            String url = util.getStringOrdefault(3,"http://192.168.80.169:12345/m")
            MySqlTest.LOG_KEY = false;
            JSONObject params = new JSONObject();
            params.put("name", "FunTester");
            params.put("password", "123456798");
            HttpGet httpGet = getHttpGet(url, params);
            RequestThreadTimes requestThreadTimes = new RequestThreadTimes(httpGet, times);
            Concurrent funTester = new Concurrent(requestThreadTimes, thread, "FunTester测试反射执行");
            funTester.start();
        }
    
        public static void main(String args) {
            main(args.split(COMMA));
        }
    
    
        public static void main(Integer a, Integer b, Integer c) {
            main(new String[]{a + EMPTY, b + EMPTY, c + EMPTY});
        }
    
        public static void main(Integer a, Integer b, Integer c, String url) {
            main(new String[]{a + EMPTY, b + EMPTY, c + EMPTY, url});
        }
    
    
    }
    
    

    这里使用了public static void main(String[] args)方法是为了脚本化执行用例,但是在实际测试当中,发现无法解决String[] args类型的参数传递,所以我多重载写了一个方法main(String args),而另外一个方法main(Integer a, Integer b, Integer c)只是为了展示更多不同的参数的写法,而方法main(Integer a, Integer b, Integer c, String url)是为了展示方法的暴露参数和自定义功能,特别注意:禁止使用基础数据类型参数

    slave测试机

    这个逻辑通过简单的轮询去master调度机提供的接口获取测试任务或者测试用例。然后解析,执行测试用例。

    package com.funtest.groovytest
    
    import com.alibaba.fastjson.JSONArray
    import com.funtester.frame.execute.ExecuteSource
    import com.funtester.httpclient.FunLibrary
    
    class Dcs2 extends FunLibrary {
    
        public static void main(String[] args) {
            while (true) {
                String url = "http://host.docker.internal:12345/m"
                //请求此接口会返回一个用例,目前没有用对象封装
                def get = getHttpGet(url)
                def response = getHttpResponse(get)
                if (response.getInteger("code") == 0) {
                    def data = response.getJSONObject("data")
                    def path = data.getString("path")
                    JSONArray array = data.getJSONArray("paramsType")
                    ExecuteSource.executeMethod(path, array.toArray())
                }
                sleep(5.0)
            }
        }
    
    
    }
    
    

    逻辑同方案(一)这里不多说了。

    控制台输出:

    INFO-> 当前用户:oker,工作目录:/Users/oker/IdeaProjects/funtester/,系统编码格式:UTF-8,系统Mac OS X版本:10.16
    INFO-> 请求uri:http://localhost:12345/t , 耗时:368 ms , HTTPcode: 200
    INFO-> =========预热完成,开始测试!=========
    INFO-> FunTester测试反射执行进度:▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍  100%
    INFO-> 总计10个线程,共用时:0.505 s,执行总数:973,错误数:0,失败数:0
    INFO-> 数据保存成功!文件名:/Users/oker/IdeaProjects/funtester/long/data/FunTester测试反射执行021904_10
    INFO-> 
    ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
    >  {
    >  ① . "rt":4,
    >  ① . "failRate":0.0,
    >  ① . "threads":10,
    >  ① . "deviation":"22.93%",
    >  ① . "errorRate":0.0,
    >  ① . "executeTotal":973,
    >  ① . "qps2":1926.7326732673268,
    >  ① . "total":1637,
    >  ① . "qps":2500.0,
    >  ① . "startTime":"2021-06-02 19:04:24",
    >  ① . "endTime":"2021-06-02 19:04:25",
    >  ① . "mark":"FunTester测试反射执行021904",
    >  ① . "table":"eJzj5VIgDNxK80JSi0tSi55t7X6xfurT/t6nG1qedS5/sbBHwdBAoSSjKDUxhQhzFHi5ePHbF5RaXJCfV5yqEJKZm2qlUKFbnFqUmZijkFeaq6NQqZubmpKZmEfIDmJckpuZpwAxzcpIIbdYJzexwsoSyKCKLygFj6Z1ABGRPhm1ZdSWwWnLo2ntQEQfm8BWDHmbHk1rAiJcFG1tRjYdHzVqMyk2tAIRORTtXUasDeRSQ9plj6Y1AhFJ1KBwNa0dMerqIeBq8ksdEgufAfDZIHDMqM9GvM8GhTNGfTjqw1EfDrwzRn046kO8PgQA59EyOA=="
    >  }
    ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
    
    Process finished with exit code 1
    
    

    性能测试结果图形化展示

    server被测服务

    内容通方案(一)这里依然不分享了。

    日志如下:

    Request received:
    
    GET /m HTTP/1.1
    Host: 192.168.80.169:12345
    Connection: Keep-Alive
    User-Agent: Apache-HttpClient/4.5.6 (Java/1.8.0_281)
    Accept-Encoding: gzip,deflate
    content-length: 0
    
    Response return:
    
    HTTP/1.1 200
    Content-Length: 18
    Content-Type: text/plain; charset=utf-8
    
    hello funtester!!!
    

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

    点击阅读原文,查看公众号历史文章

  • 相关阅读:
    service
    Specify the input method type
    添加机型
    高数公式
    MacOS 常用终端命令大全
    Linux-常用命令大全
    Mac系统下利用ADB命令使用
    iOS工程师学习Android开发----AndroidStudio环境准备
    封装socket 到vue2.x 使用
    记录一次因为OutOfMemoryError而发现的Excel文件导入慢的优化思路
  • 原文地址:https://www.cnblogs.com/FunTester/p/14891139.html
Copyright © 2011-2022 走看看