zoukankan      html  css  js  c++  java
  • 如何mock固定QPS的接口

    在做接口测试的时候,经常会遇到一些接口去调用其他服务接口,或者调用第三方接口。在进行压测的时候就会遇到问题,因为很难隔离掉其他服务和第三方接口的性能变化情况,虽然单独维护一套压测环境可以解决服务调用的问题,但是这需要很多资源和精力投入,并不一定适合每个团队。至于第三方就更难掌握,能够提供一些性能数据就很不错了。

    为此我们需要用到mock一个固定QPS的接口这样的功能。我的解决方案是基于moco API,利用本身提供的功能做一些尝试,很不幸失败了,在花费一个小时左右翻阅官方文档和实现Demo以及自己尝试发现这条路走不通。

    只能无奈放弃,然后自己拓展这个功能了。采取的方案是JDK中的Semaphore类控制流量,然后通过创建自定义ResponseHandler来完成接口的限流,思路是拿到令牌的请求线程休眠一段时间再去释放令牌完成响应。

    经过我的测试误差都在10%以内,如果是测试方案设计得好,误差应该是5%以内,这里有几条规律:

    • 请求线程越多,误差越小
    • 请求次数越多,误差越小
    • 系统充分预热,误差越小

    测试过程,改天录个视频给大家分享。

    使用Demo

            HttpServer server = getServer(8088)
    
            server.get(urlOnly("/aaa")).response(qps(textRes("faun"), 10))
    
            server.response("haha")
    
            MocoServer drive = run(server)
    
    
            waitForKey("fan")
    
            drive.stop()
    

    封装方法

    
    /**
     * 创建固定QPS的ResponseHandler,默认QPS=1
     * @param handler
     * @return
     */
        static ResponseHandler qps(ResponseHandler handler) {
            QPSHandler.newSeq(handler, 1000)
        }
    
    /**
     * 创建固定QPS的ResponseHandler
     * @param handler
     * @param gap
     * @return
     */
        static ResponseHandler qps(ResponseHandler handler,int gap) {
            QPSHandler.newSeq(handler, gap)
        }
        
    

    ResponseHandler实现类

    
    package com.fun.moco.support
    
    
    import com.github.dreamhead.moco.ResponseHandler
    import com.github.dreamhead.moco.handler.AbstractResponseHandler
    import com.github.dreamhead.moco.internal.SessionContext
    import com.github.dreamhead.moco.util.Idles
    
    import java.util.concurrent.Semaphore
    import java.util.concurrent.TimeUnit
    
    import static com.google.common.base.Preconditions.checkArgument 
    /**
     * 固定QPS的接口实现类
     */
    class QPSHandler extends AbstractResponseHandler {
    
    
        private static final Semaphore semaphore = new Semaphore(1, true);
        /**
         * 访问间隔
         */
        private final int gap
    
        private final ResponseHandler handler
    
        private QPSHandler(ResponseHandler handler, int gap) {
            this.gap = gap
            this.handler = handler
        }
    
        public static ResponseHandler newSeq(final ResponseHandler handler, int gap) {
            checkArgument(handler != null, "responsehandler 不能为空!");
            return new QPSHandler(handler, gap);
        }
    
    
    /**
     * 具体实现,这里采用微秒,实验证明微秒更准确
     * @param context
     */
        @Override
        void writeToResponse(SessionContext context) {
            semaphore.acquire()
            Idles.idle(gap * 1000, TimeUnit.MICROSECONDS)
            handler.writeToResponse(context)
            semaphore.release()
        }
    
    }
    
    

    • 郑重声明:“FunTester”首发,欢迎关注交流,禁止第三方转载。更多原创文章:FunTester十八张原创专辑,合作请联系Fhaohaizi@163.com

    热文精选

  • 相关阅读:
    centos 安装 TortoiseSVN svn 客户端
    linux 定时任务 日志记录
    centos6.5 安装PHP7.0支持nginx
    linux root 用户 定时任务添加
    composer 一些使用说明
    laravel cookie写入
    laravel composer 安装指定版本以及基本的配置
    mysql 删除重复记录语句
    linux php redis 扩展安装
    linux php 安装 memcache 扩展
  • 原文地址:https://www.cnblogs.com/FunTester/p/12970934.html
Copyright © 2011-2022 走看看