参考:
https://www.cnblogs.com/l199616j/p/12156600.html
https://blog.csdn.net/alex_yangchuansheng/article/details/116141868
1、简介
wrk是一款HTTP基准测试工具,高并发低损耗,安装部署简单,不适合多协议及复杂场景 ,适用场景:单机&单接口性能基准验证。
2、wrk 的参数
wrk 中并没有 qps 控制的选项, 它只能控制连接数目, 指定的连接数会平均分配到每个线程
例如wrk -t8 -c1000
就是启动 8 个线程, 每个线程维持 125 个连接
连接数与并发数关系
1s 内可以处理的请求数目被称为 qps.
考虑这样一个问题, 假如你想拥有 1000qps 的效果, 而你的处理能力是 0.2s 一个请求, 假设服务器足够多, 那么在这 1s 内,怎么能拥有 1000 次请求?
可以将 1s 分成 5 份(0.2s), 然后 1000 个请求在 5 份中平均的发生, 每一份就有 200 个请求, 因此我们需要 200 个并发连接.
3、压测步骤
1)寻找最大线程数:
a.固定连接数,持续时间,调高线程数;
b.当线程数增加QPS不再明显变化,且平均响应时间变高时,即为最佳线程数;
2)寻找QPS峰值:
a.固定线程数为最大线程数,固定持续时间,调整连接数;
b.当连接数增加QPS不再明显变化,且平均响应时间变高时,即为QPS峰值;
4、参数说明
1).参数说明
~ wrk
Usage: wrk <options> <url>
Options:
-c, --connections <N> 连接数
-d, --duration <T> 持续时间
-t, --threads <N> 线程数
-s, --script <S> 制定lua脚本
-H, --header <H> 添加请求头
--latency 显示响应时间分布
--timeout <T> 设置请求超时
-v, --version 打印版本信息
<N>表示数字参数,支持国际单位 (1k, 1M, 1G)
<T>表示时间参数,支持国际单位 (2s, 2m, 2h)
-t 线程数 线程数不宜过多. 核数的2到4倍足够了
ps:
使用lua脚本,一般修改method, header, body不会影响测试端性能,但是操作 request, response 可能会有影响。
2).返回结果参数
Avg 平均响应时间
Stdev 标准偏差
Max 最大值
+/- Stdev 正负标准差占比Req/Sec每个线程每秒钟的完成的请求数
Transfer/sec 每秒钟读取的数据量
Requests/sec QPS
5、简单压测及结果分析
做一个简单的压测,分析下结果:
wrk -t8 -c200 -d30s --latency http://www.bing.com
输出:
Running 30s test @ http://www.bing.com
8 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 46.67ms 215.38ms 1.67s 95.59%
Req/Sec 7.91k 1.15k 10.26k 70.77%
Latency Distribution
50% 2.93ms
75% 3.78ms
90% 4.73ms
99% 1.35s
1790465 requests in 30.01s, 684.08MB read
Requests/sec: 59658.29
Transfer/sec: 22.79MB
以上是使用8个线程200个连接,对bing首页进行了30秒的压测,并要求在压测结果中输出响应延迟信息。
以下是解释压测结果:
Running 30s test @ http://www.bing.com (压测时间30s)
8 threads and 200 connections (共8个测试线程,200个连接)
Thread Stats Avg Stdev Max +/- Stdev
(平均值) (标准差)(最大值)(正负一个标准差所占比例)
Latency 46.67ms 215.38ms 1.67s 95.59%
(延迟)
Req/Sec 7.91k 1.15k 10.26k 70.77%
(处理中的请求数)
Latency Distribution (延迟分布)
50% 2.93ms
75% 3.78ms
90% 4.73ms
99% 1.35s (99分位的延迟:%99的请求在1.35s以内)
1790465 requests in 30.01s, 684.08MB read (30.01秒内共处理完成了1790465个请求,读取了684.08MB数据)
Requests/sec: 59658.29 (平均每秒处理完成59658.29个请求)
Transfer/sec: 22.79MB (平均每秒读取数据22.79MB)
6、使用lua脚本进行压测
lua脚本是一种轻量小巧的脚本语言,用标准c语言编写,并以源代码形式开放,其设计目的是为了嵌入应用程序中,从而为程序提供灵活的扩展和定制功能。wrk工具嵌入了lua脚本语言,因此,在自定义压测场景时,可在wrk目录下使用lua定制压测场景。
1)lua声明周期
共有三个阶段,启动阶段,运行阶段,结束阶段。wrk支持在这三个阶段对压测进行个性化。
运行阶段
function init(args) --由测试线程调用,只会在进入运行阶段时,调用一次。支持从启动wrk的命令中,获取命令行参数;
function delay() --在每次发送request之前调用,如果需要delay,那么delay相应时间;
function request() --用来生成请求;每一次请求都会调用该方法,所以注意不要在该方法中做耗时的操作;
function response(status, headers, body) --在每次收到一个响应时调用;为提升性能,如果没有定义该方法,那么wrk不会解析headers和body;
2)自定义脚本中可访问的变量和方法:
wrk = {
scheme = "http",
host = "localhost",
port = nil,
method = "GET",
path = "/",
headers = {},
body = nil,
thread = <userdata>,
}
方法:wrk.fomat wrk.lookup wrk.connect
function wrk.format(method, path, headers, body) --根据参数和全局变量wrk,生成一个HTTP rquest string。
function wrk.lookup(host, service) --给定host和service(port/well known service name),返回所有可用的服务器地址信息。
function wrk.connect(addr) --测试与给定的服务器地址信息是否可以成功创建连接
3)lua脚本压测实例
压测命令: wrk -t1 -c1 -d10s --latency -s colorpick_new.lua https://ditto.devops.xiaohongshu.com
colorpick_new.lua 是用lua写的压测脚本,如下是压测脚本的实例:
使用get方法压测
urimap = {}
counter = 0
function init(args)
responses_ok = 0
responses = 0
for line in io.lines("colorpick_new.txt") do --wrk读取文件,colorpick_new.txt对imgUrl进行参数化
-- print(line)
urimap[counter] = line
counter = counter + 1
end
counter = 0
end
request = function()
local path ="/fe_api/lugia/ditto/color/colorPicker?imgUrl=%s"
parms = urimap[counter%(table.getn(urimap) + 1)]
path = string.format(path,parms)
-- print(path)
counter = counter + 1
print(wrk.format(nil, path) )
return wrk.format(nil, path)
end
response = function(status, headers, body)
flag = string.find(body, '"success":true') --flag判断服务器返回是否包含字符串 '"success":true'
-- print(flag)
print(body)
if flag ~= nil then --flag不为空计算正常返回请求个数
responses_ok = responses_ok + 1
else
-- print(body)
responses = responses + 1
print(responses)
end
end
使用post方法压测
脚本如下:
wrk.method = "POST"
wrk.headers["content-type"] = "application/json"
wrk.body = '{"albumFileDtos":[{"actions":["theme_res_body"],"fileId":"f74ff680-5e98-359a-89de-2e6c0c849d58"}]}'
init = function(args)
requests = 0
responses = 0
responses_ok = 0
totalTime = 0
end
response = function(status, headers, body)
flag = string.find(body, 'result":0')
if flag ~= nil then
responses_ok = responses_ok + 1
else
print(body)
responses = responses + 1
end
end
压测命令:
wrk -t5 -c10 -d180s -H 'Host: www.beta.xiaohongshu.com' -H 'content-type: application/json' -H 'xy-platform-info: platform=iOS&version=7.3&build=7030184&deviceId=25064D2E-DDC2-4E43-A9D1-200843DBCE88&bundle=com.xingin.discover' -H 'x-raw-ptr: 0' -H 'x-net-core: crn' -H 'x-b3-traceid: 174050015d9597a4' -H 'accept-language: zh-Hans-CN;q=1, en-US;q=0.9' -H 'mode: rawIp' -H 'user-agent: discover/7.3 (iPhone; iOS 12.4.1; Scale/3.00) Resolution/1125*2436 Version/7.3 Build/7030184 Device/(Apple Inc.;iPhone11,2) NetType/WiFi' -H 'xy-common-params: app_id=ECFAAF02&build=7030184&deviceId=25064D2E-DDC2-4E43-A9D1-200843DBCE88&device_fingerprint=201902161307039e51cd49af86b4798572a7d0f6c3c64e010de111a5578b63&device_fingerprint1=201902161307039e51cd49af86b4798572a7d0f6c3c64e010de111a5578b63&fid=1576927051-0-0-7b5cf3e42a8d89599e24bfb81d7e8076&identifier_flag=1&lang=zh-Hans&launch_id=649922878&platform=iOS&project_id=ECFAAF&sid=session.1628154473871380939559&t=1628237319&tz=Asia/Shanghai&version=7.3' -H 'shield: XYAAAAAQAAAAEAAABTAAAAUzUWEe4xG1IYD9/c+qCLOlKGmTtFa+lG43EOf+FXTKlAwIS2msJlOZ2Mi5Ndz8Rf2M5+oKtGEQxMEWWAYLiArlgVjuwg3M0OFVzYZV05SQ5khcwR' -H 'accept: */*' --latency -s test.lua http://www.beta.xiaohongshu.com/api/sns/v1/media/generate_album
网友评论