zoukankan      html  css  js  c++  java
  • wrk性能测试工具使用

    https://www.cnblogs.com/poloyy/p/14872021.html
    wrk性能测试工具的使用:
    下载:
    https://github.com/giltene/wrk2
    安装:
    yum -y install gcc automake autoconf libtool make
    yum install gcc++
    yum install openssl-devel  或者
    yum install libssl-dev
    # git clone https://github.com/giltene/wrk2.git 下载源码
    # cd wrk2  安装目录
    # make
    ln -s /export/ccc/wrk2-master/wrk /usr/local/bin
    参数设定经验:
    线程数: -t 依据cpu核数来设定,最大值不要超过2倍cpu核数
    连接数:-c 并发数,连接数需要在测试过程中多次调试,找到QPS达到最大临界点的
    最大并发量;由于服务器有自身的负载极限,也会出现连接数越大QPS越低的情况,这种情况是因为
    连接数设置的过高,导致待测系统超出自身能承受的负载。
    吞吐量: -R 是每个线程每秒完成的请求数,这个数值是wrk2必带的一个参数,在测试过程中
    也是需要测试人员多次调试,通过不断上调其数值,测试出QPS的临界值及保证服务
    可用的时延。

    命令:

    path: 该字符串会拼到 http://ip 后
    wrk.format 介绍:{
        根据参数和全局变量wrk生成一个http请求函数签名:
        function wrk.format(method, path, headers, body)
        method:     请求方法
        path:      路径
        headers: 请求头
        body:      参数
    }

    7.lua声明周期
    共有三个阶段,启动阶段,运行阶段,结束阶段
    启动阶段:
        function setup(thread) :
            wrk会在线程初始化但还没有启动的时候调用setup(thread)方法。且每个线程都会调用一次,并传入测试线程的对象thread作为参数。
            thread.addr 设置请求需要打到的ip
            thread:get(name) 获取线程全局变量
            thread:set(name, value) 设置线程全局变量
            thread:stop() 终止线程

    运行阶段:
        function init(args) -- 每个线程都会先调用1次,其中可以做一些初始化工作,比如读测试数据
        delay() -- 每次请求调用1次,发送下一个请求之前的延迟, 单位为ms
        function request() -- 每次请求调用1次,返回http请求
        function response(status, headers, body) -- 每次请求调用1次,返回http响应



    lua脚本:
    #testcase1:
    -------------------------------
    #wrk -t1 -c1 -d1s --latency -R 1 -s test.lua http://10.50.36.40/
    #test.lua压测脚本内容:这里模拟一个post请求,data为消息体,每次请求生成一个uuid,保证数据的不重复
    request= function()
    local uuid = io.open("/proc/sys/kernel/random/uuid", "r"):read()
    local data = [[{
        "table_data":[
            {
            "create_time":"2021-02-03 21:34:44",
            "description":"%s"}
            ],
        "table_name":"tab_record"
        }]]
    wrk.method = "POST"
    wrk.body   =string.format(data,tostring(uuid))
    wrk.headers["Content-Type"] = "application/json"
    return wrk.format()
    end

    #testcase2:
    ------------------------------
    #发送随机参数
    request = function()
    num = math.random(1000,9999)
    path = "/test.html?t=" .. num
    return wrk.format("GET", path)
    end

    #testcase3:
    ----------------------------------------------------------------
    #从文件中依次选择参数,适用于多条固定的参数测试(table.getn()是获取集合的长度)
    idArr = {}
    falg = 0
    function init(args)
        for line in io.lines("ids.txt") do
           print(line)
           idArr[falg] = line
           falg = falg + 1
       end
       falg = 0
    end
     
    request = function()
    local path ="/getInfo?id=%s"
    parms = idArr[falg%(table.getn(idArr) + 1)]
    path = string.format(path,parms)
    falg = falg + 1
    return wrk.format(nil, path)
    end

    #testcase4:
    ---------------------------------------------------
    #发送多个请求:
    init = function(args)
       local r = {}
       r[1] = wrk.format(nil, "/info/getInfoById?id=100001&channel=0")
       r[2] = wrk.format(nil, "/info/getByName?name=aaa&startindex=0&length=10")
       r[3] = wrk.format(nil, "/info/getByUserId?id=88888888")

       req = table.concat(r)
    end

    request = function()
       return req
    end

    #testcase5:
    ----------------------------------------------------------
    -- example script that demonstrates use of setup() to pass
    -- data to and from the threads

    local counter = 1
    local threads = {}

    function setup(thread)
    -- 给每个线程设置一个 id 参数
       thread:set("id", counter)
    -- 将线程添加到 table 中
       table.insert(threads, thread)
       counter = counter + 1
    end

    function init(args)
    -- 初始化两个参数,每个线程都有独立的 requests、responses 参数
       requests  = 0
       responses = 0

    -- 打印线程被创建的消息,打印完后,线程正式启动运行
       local msg = "thread %d created"
       print(msg:format(id))
    end

    function request()
    -- 每发起一次请求 +1
       requests = requests + 1
       return wrk.request()
    end

    function response(status, headers, body)
    -- 每得到一次请求的响应 +1
       responses = responses + 1
    end

    function done(summary, latency, requests)
    -- 循环线程 table
       for index, thread in ipairs(threads) do
          local id        = thread:get("id")
          local requests  = thread:get("requests")
          local responses = thread:get("responses")
          local msg = "thread %d made %d requests and got %d responses"
    -- 打印每个线程发起了多少个请求,得到了多少次响应
          print(msg:format(id, requests, responses))
       end
    end

    #testcase6:
    ---------------------------------------------------
    --导入Lua库
    local json = require "json"
    local md5 = require "md5"
    local random = math.random
    local uuid = require 'uuid'

    -- 声明一些实际工作中,接口需要用的的变量
    local secret = "platform_secret"

    local pkg_info = {
        is_simulator = false
    }

    -- 提前声明请求体
    local req = {
        game = "",
        secret = "b",
        server = "c",
        guest = false,
        platform = "d",
        pkg_info = pkg_info
    }

    -- 修改请求头,所有请求均生效
    wrk.headers["Content-Type"] = "application/json"

    -- 官方例子的写法,这里加上
    local counter = 1
    local threads = {}

    function setup(thread)
        thread:set("id",counter)
        table.insert(threads,thread)
        counter = counter + 1
    end

    function init(args)
        math.randomseed(id)
    end

    local upv = 100000000

    -- 自定义一个方法
    local function random_uid()
        return 'testuid' .. tostring(upv * id + random(0,upv))
    end

    --自定义一个方法,并返回字符串
    function create_UUID()
        local template = "xxxxxxxxxxxxxxxxxxxxx"
        d = io.open("/dev/urandom","r"):read(4)
        math.randomseed(os.time() + d:byte(1) + (d:byte(2) * 256) + (d:byte(3) * 65536) + (d:byte(4) * 42949
        67296))
        return string.gsub(template,"x",function(c)
        local v = (c == "x") and math.random(0,0xf) or math.random(8,0xb)
        return string.format("%x", v)
        end)
    end

    function request()
    --给 req 对象加两个参数pid、ptokn
        req.pid = uuid.generate()
        req.ptoken = md5.sumhexa(req.pid .. secret)
        
    --打印下看看对不对
        print(json.encode(req))
        
    --返回自定义的HTTP请求字符串,动态创建了一个请求
        return wrk.format("POST". wrk.path. wrk.headers. json.encode(req))
        
    function response(status, headers, body)
    -- 如果响应码 != 200 则打印 body 并且返回
        if status ~= 200 then
            print(body)
        return
        end
        
    -- 打印响应体(仅调试用,正式测试需要注释掉print)
        local resp = json.decode(body)
        print(body)
        
    -- 如果响应体的 code != 0 (一般就是后端返回码错误码)
        if resp.code ~= 0 then
    -- 打印body,并返回
            print(json.encode(req)..'-->'..body)
            return
        end
    end


    --导入 Lua 库
    local json = require "json"
    local md5 = require "md5"
    local random = math.random
    local uuid = require 'uuid'

    -- 声明一些实际工作中,接口需要用到的变量
    local secret = "platform_secret"

    local pkg_info = {
        is_simulator = false
    }

    -- 提前声明请求体
    local req = {
        game = "",
        secret = "b",
        server = "c",
        guest = false,
        platform = "d",
        pkg_info = pkg_info
    }

    -- 修改请求头,所有请求均生效
    wrk.headers["Content-Type"] = "application/json"

    -- 官方例子的写法,这里加上
    local counter = 1
    local threads = {}

    function setup(thread)
        thread:set("id",counter)
        table.insert(threads,thread)
        counter = counter + 1
    end

    function init(args)
        math.randomseed(id)
    end

    local upv = 100000000

    -- 自定义一个方法
    local function random_uid()
        return 'testuid' .. tostring(upv * id + random(0,upv))
    end

    -- 自定义一个方法,并返回字符串
    function create_UUID()
        local template = "xxxxxxxxxxxxxxxxxxxxx"
        d = io.open("/dev/urandom","r"):read(4)
        math.randomseed(os.time() + d:byte(1) + (d:byte(2) * 256) + (d:byte(3) * 65546) + (d:byte(4) * 4294967296))
        return string.gsub(template,"x",function(c)
        local v = (c == "x") and math.random(0,0xf) or math.random(8,0xb)
        return string.format("%x",v)
        end)
    end

    function request()
    -- 给req 对象加两个参数pid、ptoken
        req.pid = uuid.generate()
        req.ptoken = md5sumhexa(req.pid .. secret)
        
    -- 打印下看看对不对
        print(json.encode(req))
        
    -- 打印下看看对不对
        print(json.encode(req))
        
    -- 返回自定义的 HTTP 请求字符串,动态创建了一个请求
        return wrk.format("POST". wrk.path. wrk.headers. json.encode(req))
        
    function response(status, headers, body)
    -- 如果响应码 != 200 则打印 body 并且返回
            if status ~= 200 then
                print(body)
            return
            end
        
    -- 打印响应体(仅调试用,正式测试需要注释掉 print)
        local resp = json.decode(body)
        print(body)

    -- 如果响应体的 code != 0 (一般就是后端返回码错误)
        if resp.code ~= 0 then
    -- 打印body,并返回
            print(json.encode(req)..'-->'..body)
            return
        end
    end

    请尊重笔者的劳动成果哦,转载请说明出处哦
  • 相关阅读:
    ME05 黑匣子思维
    F06 《生活中的投资学》摘要(完)
    ME03 关于运气要知道的几个真相
    ME02 做一个合格的父母To be good enough parent
    ME02 认知之2017罗胖跨年演讲
    F03 金融学第三定律 风险共担
    F05 敏锐的生活,让跟多公司给你免单
    ML04 Accord 调用实现机器算法的套路
    D02 TED Elon Mulsk The future we're building — and boring
    ML03 利用Accord 进行机器学习的第一个小例子
  • 原文地址:https://www.cnblogs.com/gufengchen/p/15737173.html
Copyright © 2011-2022 走看看