博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
web压力测试工具wrk安装及使用
阅读量:7074 次
发布时间:2019-06-28

本文共 6110 字,大约阅读时间需要 20 分钟。

用过了很多压测工具,却一直没找到中意的那款。最近试了wrk感觉不错,写下这份使用指南给自己备忘用,如果能帮到你,那也很好。

安装

wrk支持大多数类UNIX系统,不支持windows。需要操作系统支持LuaJIT和OpenSSL,不过不用担心,大多数类Unix系统都支持。安装wrk非常简单,只要从github上下载wrk源码,在项目路径下执行make命令即可。

git clone https://github.com/wg/wrkmake

make之后,会在项目路径下生成可执行文件wrk,随后就可以用其进行HTTP压测了。可以把这个可执行文件拷贝到某个已在path中的路径,比如/usr/local/bin,这样就可以在任何路径直接使用wrk了。

默认情况下wrk会使用自带的LuaJIT和OpenSSL,如果你想使用系统已安装的版本,可以使用WITH_LUAJIT和WITH_OPENSSL这两个选项来指定它们的路径。比如:

make WITH_LUAJIT=/usr WITH_OPENSSL=/usr

mac 下快捷安装

brew install wrk

基本使用

命令行敲下wrk,可以看到使用帮助

Usage: wrk 
Options: -c, --connections
Connections to keep open -d, --duration
Duration of test -t, --threads
Number of threads to use -s, --script
Load Lua script file -H, --header
Add header to request --latency Print latency statistics --timeout
Socket/request timeout -v, --version Print version details Numeric arguments may include a SI unit (1k, 1M, 1G) Time arguments may include a time unit (2s, 2m, 2h)

简单翻成中文:

使用方法: wrk 
<选项>
<被测http服务的url>
Options: -c, --connections
跟服务器建立并保持的TCP连接数量 -d, --duration
压测时间 -t, --threads
使用多少个线程进行压测 -s, --script
指定Lua脚本路径 -H, --header
为每一个HTTP请求添加HTTP头 --latency 在压测结束后,打印延迟统计信息 --timeout
超时时间 -v, --version 打印正在使用的wrk的详细版本信息
代表数字参数,支持国际单位 (1k, 1M, 1G)
代表时间参数,支持时间单位 (2s, 2m, 2h)

看下版本

wrk -v输出:wrk 4.0.2 [epoll] Copyright (C) 2012 Will Glozer

看到是4.0.2版本的wrk,使用了epoll。这意味着我们可以用少量的线程来跟被测服务创建大量连接,进行压测。

做一次简单压测,分析下结果

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 readRequests/sec:  59658.29Transfer/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分位的延迟)  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)

可以看到,wrk使用方便,结果清晰。并且因为非阻塞IO的使用,可以在普通的测试机上创建出大量的连接,从而达到较好的压测效果。

使用Lua脚本个性化wrk压测

以上两节安装并简单使用了wrk,但这种简单的压测可能不能满足我们的需求。比如我们可能需要使用POST METHOD跟服务器交互;可能需要为每一次请求使用不同的参数,以更好的模拟服务的实际使用场景等。wrk支持用户使用--script指定Lua脚本,来定制压测过程,满足个性化需求。

介绍wrk对Lua脚本的支持

wrk支持在三个阶段对压测进行个性化,分别是启动阶段、运行阶段和结束阶段。每个测试线程,都拥有独立的Lua运行环境。

启动阶段

function setup(thread)

在脚本文件中实现setup方法,wrk就会在测试线程已经初始化但还没有启动的时候调用该方法。wrk会为每一个测试线程调用一次setup方法,并传入代表测试线程的对象thread作为参数。setup方法中可操作该thread对象,获取信息、存储信息、甚至关闭该线程。

thread.addr             - get or set the thread's server addressthread:get(name)        - get the value of a global in the thread's envthread:set(name, value) - set the value of a global in the thread's envthread:stop()           - stop the thread

运行阶段

function init(args)function delay()function request()function response(status, headers, body)

init由测试线程调用,只会在进入运行阶段时,调用一次。支持从启动wrk的命令中,获取命令行参数;

delay在每次发送request之前调用,如果需要delay,那么delay相应时间;
request用来生成请求;每一次请求都会调用该方法,所以注意不要在该方法中做耗时的操作;
reponse在每次收到一个响应时调用;为提升性能,如果没有定义该方法,那么wrk不会解析headers和body;

结束阶段

function done(summary, latency, requests)

该方法在整个测试过程中只会调用一次,可从参数给定的对象中,获取压测结果,生成定制化的测试报告。

自定义脚本中可访问的变量和方法

变量:wrk

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

一个table类型的变量wrk,是全局变量,修改该table,会影响所有请求。

方法:wrk.fomat wrk.lookup wrk.connect

function wrk.format(method, path, headers, body)    wrk.format returns a HTTP request string containing the passed parameters    merged with values from the wrk table.    根据参数和全局变量wrk,生成一个HTTP rquest string。  function wrk.lookup(host, service)    wrk.lookup returns a table containing all known addresses for the host    and service pair. This corresponds to the POSIX getaddrinfo() function.    给定host和service(port/well known service name),返回所有可用的服务器地址信息。  function wrk.connect(addr)    wrk.connect returns true if the address can be connected to, otherwise    it returns false. The address must be one returned from wrk.lookup().    测试与给定的服务器地址信息是否可以成功创建连接

示例

使用POST METHOD

wrk.method = "POST"wrk.body   = "foo=bar&baz=quux"wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"

通过修改全局变量wrk,使得所有请求都使用POST方法,并指定了body和Content-Type头。

为每次request更换一个参数

request = function()   uid = math.random(1, 10000000)   path = "/test?uid=" .. uid   return wrk.format(nil, path)end

通过在request方法中随机生成1~10000000之间的uid,使得请求中的uid参数随机。

每次请求之前延迟10ms

function delay()   return 10end

每个线程要先进行认证,认证之后获取token以进行压测

token = nilpath  = "/authenticate"request = function()   return wrk.format("GET", path)endresponse = function(status, headers, body)   if not token and status == 200 then      token = headers["X-Token"]      path  = "/resource"      wrk.headers["X-Token"] = token   endend

在没有token的情况下,先访问/authenticate认证。认证成功后,读取token并替换path为/resource。

压测支持HTTP pipeline的服务

init = function(args)   local r = {}   r[1] = wrk.format(nil, "/?foo")   r[2] = wrk.format(nil, "/?bar")   r[3] = wrk.format(nil, "/?baz")   req = table.concat(r)endrequest = function()   return reqend

通过在init方法中将三个HTTP request请求拼接在一起,实现每次发送三个请求,以使用HTTP pipeline。

转载自:

你可能感兴趣的文章
玩转算法面试:(三)LeetCode数组类问题
查看>>
kali:加速WEP黑客攻击,ARP请求重播攻击
查看>>
C# 添加、获取及删除PDF附件
查看>>
华为S5300系列交换机V200R001SPH027升级补丁
查看>>
CISP-PTE注册信息安全专业人员渗透测试工程师知识体系大纲
查看>>
移动web开发中,好用的小方法
查看>>
Go 语言的垃圾回收演化历程:垃圾回收和运行时问题
查看>>
【Java资源免费分享,网盘自己拿】
查看>>
webpack配置(第四步:html篇(进阶篇))
查看>>
Spring Boot开启的2种方式
查看>>
阿里云服务提供商分享CDN访问异常该如何排查
查看>>
利用Sympy计算sin1°的最小多项式
查看>>
Vuejs响应式原理
查看>>
【Nebula系列】C++反射机制:可变参数模板实现C++反射
查看>>
mac 终端 常用命令
查看>>
2016年人工智能产业梳理:一朝引爆,稳步前进(下篇)
查看>>
django 1.8 官方文档翻译:5-1-2 表单API
查看>>
区块链将会怎样颠覆Google、Amazon、Facebook和Apple?
查看>>
VR直播很火,但能取代传统电视直播吗?
查看>>
[转]区块链代码快速学习实践
查看>>