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
