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

    请尊重笔者的劳动成果哦,转载请说明出处哦
  • 相关阅读:
    笔记44 Hibernate快速入门(一)
    tomcat 启用https协议
    笔记43 Spring Security简介
    笔记43 Spring Web Flow——订购披萨应用详解
    笔记42 Spring Web Flow——Demo(2)
    笔记41 Spring Web Flow——Demo
    Perfect Squares
    Factorial Trailing Zeroes
    Excel Sheet Column Title
    Excel Sheet Column Number
  • 原文地址:https://www.cnblogs.com/gufengchen/p/15737173.html
Copyright © 2011-2022 走看看