使用wrk做测试

389 阅读3分钟

1. 使用wrk做测试

1. 下载源码,编译安装

[root@opinion-96 wrk]# git clone https://gitee.com/why168/wrk.git
[root@opinion-96 wrk]# cd wrk/ && make

2. 准备要压测的接口和lua脚本

1. 接口 https://ops.cninfo.com.cn/opinions/pageQuery

2. post.lua 脚本

wrk.method = "POST"
wrk.headers["Content-Type"] = "application/json;charset=UTF-8"
wrk.body = "{\"stockCode\":\"000004\",\"pageNo\":1,\"pageSize\":10,\"keywords\":[],\"titles\":[],\"keyword\":\"\",\"startDate\":\"2021-07-27T01:04:33.204Z\",\"endDate\":\"2022-01-27T01:04:33.204Z\",\"industry\":\"\",\"customKeyword\":[],\"date\":[\"2021-07-27T01:04:33.204Z\",\"2022-01-27T01:04:33.204Z\"]}"

3. 执行测试

 ./wrk -t4 -c200 -d60s -T5s --script=post.lua --latency https://ops.cninfo.com.cn/opinions/pageQuery

参数说明:

-c, --connections: total number of HTTP connections to keep open with
                   each thread handling N = connections/threads

-d, --duration:    duration of the test, e.g. 2s, 2m, 2h

-t, --threads:     total number of threads to use

-s, --script:      LuaJIT script, see SCRIPTING

-H, --header:      HTTP header to add to request, e.g. "User-Agent: wrk"

    --latency:     print detailed latency statistics

    --timeout:     record a timeout if a response is not received within
                   this amount of time.

4. 测试结果说明

[root@opinion-96 wrk]#  ./wrk -t4 -c200 -d60s -T5s --script=post.lua --latency https://ops.cninfo.com.cn/opinions/pageQuery
Running 1m test @ https://ops.cninfo.com.cn/opinions/pageQuery
  4 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   596.64ms  656.91ms   4.92s    86.22%
    Req/Sec   114.67     39.57   262.00     70.26%
  Latency Distribution
     50%  420.30ms
     75%  871.40ms
     90%    1.47s 
     99%    2.95s 
  26926 requests in 1.00m, 281.58MB read
  Socket errors: connect 0, read 0, write 0, timeout 6
  Non-2xx or 3xx responses: 5
Requests/sec:    448.29
Transfer/sec:      4.69MB

5. 此时查看压测机

1.png

6. 当压测参数调整为 -t4 -c4 -d15m -T5s时,dstat监控显示如下:

推测应该是压测机的网卡,影响限制了压测结果

2.png

2. wrk中的lua脚本

wrk是一款现代化的http压测工具,提供lua脚本的功能可以满足每个请求或部分请求的差异化。

wrk中执行http请求的时候,调用lua分为3个阶段,setup,running,done,每个wrk线程中都有独立的脚本环境。

image.png

wrk的全局属性

wrk = {
  scheme  = "http",
  host    = "localhost",
  port    = nil,
  method  = "GET",
  path    = "/",
  headers = {},
  body    = nil,
  thread  = <userdata>,
}

wrk的全局方法

-- 生成整个request的string,例如:返回
-- GET / HTTP/1.1
-- Host: tool.lu
function wrk.format(method, path, headers, body)

-- 获取域名的IP和端口,返回table,例如:返回 `{127.0.0.1:80}`
function wrk.lookup(host, service)

-- 判断addr是否能连接,例如:`127.0.0.1:80`,返回 true 或 false
function wrk.connect(addr)

Setup阶段

setup是在线程创建之后,启动之前。

function setup(thread)

-- thread提供了1个属性,3个方法
-- thread.addr 设置请求需要打到的ip
-- thread:get(name) 获取线程全局变量
-- thread:set(name, value) 设置线程全局变量
-- thread:stop() 终止线程

Running阶段

function init(args)
-- 每个线程仅调用1次,args 用于获取命令行中传入的参数, 例如 --env=pre

function delay()
-- 每个线程调用多次,发送下一个请求之前的延迟, 单位为ms

function request()
-- 每个线程调用多次,返回http请求

function response(status, headers, body)
-- 每个线程调用多次,返回http响应

Done阶段

可以用于自定义结果报表,整个过程中只执行一次

function done(summary, latency, requests)


latency.min              -- minimum value seen
latency.max              -- maximum value seen
latency.mean             -- average value seen
latency.stdev            -- standard deviation
latency:percentile(99.0) -- 99th percentile value
latency(i)               -- raw value and count

summary = {
  duration = N,  -- run duration in microseconds
  requests = N,  -- total completed requests
  bytes    = N,  -- total bytes received
  errors   = {
    connect = N, -- total socket connection errors
    read    = N, -- total socket read errors
    write   = N, -- total socket write errors
    status  = N, -- total HTTP status codes > 399
    timeout = N  -- total request timeouts
  }
}

表单的提交

wrk.method = "POST"
wrk.body = "" -- 直接写死,如果不需要请求数据的差异化
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"

-- 如果要实现每次都不一样的表单内容
local queries = {
    "language=php",
    "language=java",
    "language=lua"
}
local i = 0
request = function()
    local body = wrk.format(nil, nil, nil, queries[i % #queries + 1])
    i = i + 1
    return body
end