zoukankan      html  css  js  c++  java
  • ThreadLocal在链路性能测试中实践

    在前面的时间,我分享两篇关于ThreadLocal类的文章:利用ThreadLocal解决线程同步问题Java中的ThreadLocal功能演示,今天以之前做过的一个链路性能测试,分享一下在ThreadLocal在测试中的简单应用。

    需求和逻辑

    需求

    需求是用户(登录状态)对某个资源(通过minisource_id确认)进行取消收藏和收藏的功能。

    业务判断依据为相应结构中在外层JSON对象的key=metavalueJSON对象,且value中的key=ecode必需为0

    逻辑

    先进行收藏,然后取消收藏,以此作为一个链路进行性能测试。这个例子我在链路压测中如何记录每一个耗时的请求中用到过,感兴趣的可以去看一下。

    思路

    根据ThreadLocal类的功能和使用场景,我在功能类OKClass中初始化了一个超长的minisource_idList对象,用来存储测试可能需要的ids。然后通过一个线程安全的AtomicInteger对象标记索引位置,方便在initialValue()方法中,返回不同的minisource_id

    具体的规则就是,每执行一次initialValue()方法,索引index增加1,这样可以保证每个线程调用功能类对象的方法时,使用的minisource_id都是不一样的。

    功能类改造

    功能类代码比较多,我就把此次修改涉及的代码分享如下:

        /**
         * 所有可用的id
         */
        public static List<Integer> ids = RWUtil.readTxtFileByNumLine(getLongFile("ids"))
    
        /**
         * 索引标记
         */
        public static AtomicInteger index = new AtomicInteger(0)
    
        /**
         * 线程不共享对象
         */
        public static ThreadLocal<Integer> minisource_id = new ThreadLocal() {
    
            @Override
            public Integer initialValue() {
                ids.get(index.getAndIncrement())
            }
        }
    
    
        /**
         * 收藏OK智课
         * @param minicourse_id
         * @param ktype 0-机构,1-老师
         * @return
         */
        public JSONObject collect(int minicourse_id = minisource_id.get(), int ktype = 0, int grade_id = 12) {
            String url = OKClassApi.COLLECT
            def params = getParams()
            params.put("minicourse_id", minicourse_id);
            params.put("kid_route", [640]);
            params.put("ktype", ktype);
            params.put("grade_id", grade_id);
            params.put("link_source", 1);//0-教师空间,1-教师机
            def response = getPostResponse(url, params)
            output(response)
            response
        }
    
        /**
         * 取消收藏
         * @param minicourse_id
         * @param ktype
         * @param grade_id
         * @return
         */
        public JSONObject unCollect(int minicourse_id = minisource_id.get(), int ktype = 0) {
            String url = OKClassApi.UNCOLLECT
            def params = getParams()
            params.put("minicourse_id", minicourse_id);
            params.put("kid_route", [82]);
            params.put("ktype", ktype);
            def response = getPostResponse(url, params)
            output(response)
            response
        }
    
    • 这里的写法有个参数默认值的,这是Groovy特性,可以当做params.put("minicourse_id", minisource_id.get());

    压测脚本

    功能不多说了,没有改动,分享如下:

    package com.okayqa.composer.performance.master1_0
    
    import com.fun.base.constaint.ThreadLimitTimesCount
    import com.fun.frame.execute.Concurrent
    import com.fun.frame.httpclient.ClientManage
    import com.fun.utils.ArgsUtil
    import com.okayqa.composer.base.OkayBase
    import com.okayqa.composer.function.OKClass
    
    import java.util.concurrent.atomic.AtomicInteger
    
    class BothCollect extends OkayBase {
    
        static AtomicInteger u = new AtomicInteger(0)
    
        static int times = 0
    
        static int thread
    
        public static void main(String[] args) {
            ClientManage.init(5, 1, 0, "", 0)
            def util = new ArgsUtil(args)
            thread = util.getIntOrdefault(0, 200)
            times = util.getIntOrdefault(1, 100)
            def funs = []
            thread.times {
                funs << new FunTester()
            }
            new Concurrent(funs, "收藏和取消收藏").start()
            allOver()
        }
    
        static int getTimes() {
            return times
        }
    
        static class FunTester extends ThreadLimitTimesCount {
    
            OkayBase okayBase = getBase(u.getAndIncrement())
    
            OKClass driver = new OKClass(okayBase)
    
            public FunTester() {
                super(null, getTimes(), null)
            }
    
    
            @Override
            protected void doing() {
                def collect = driver.collect()
                def value = okayBase.getLastRequestId() + CONNECTOR
                this.threadmark += value
                if (collect.getJSONObject("meta").getIntValue("ecode") != 0) fail(value + "请求出错!")
                def collect1 = driver.unCollect()
                def value1 = okayBase.getLastRequestId()
                this.threadmark += value1
                if (collect1.getJSONObject("meta").getIntValue("ecode") != 0) fail(value1 + "请求出错!")
            }
        }
    
    }
    
    

    FunTester腾讯云年度作者,优秀讲师 | 腾讯云+社区权威认证,非著名测试开发,欢迎关注。

  • 相关阅读:
    java+opencv实现图像灰度化
    java实现高斯平滑
    hdu 3415 单调队列
    POJ 3368 Frequent values 线段树区间合并
    UVA 11795 Mega Man's Mission 状态DP
    UVA 11552 Fewest Flops DP
    UVA 10534 Wavio Sequence DP LIS
    UVA 1424 uvalive 4256 Salesmen 简单DP
    UVA 1099 uvalive 4794 Sharing Chocolate 状态DP
    UVA 1169uvalive 3983 Robotruck 单调队列优化DP
  • 原文地址:https://www.cnblogs.com/FunTester/p/14385456.html
Copyright © 2011-2022 走看看