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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM