searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

wrk - 简单易用的web压测工具

2023-06-14 10:54:17
142
0

简介

wrk 是一款针对 Http/Https 协议的基准测试工具,它能够在单机多核 CPU 的条件下,使用系统自带的高性能 I/O 机制,如 epoll,kqueue 等,通过多线程和事件模式,对目标机器产生大量的负载。

优势:

1,  安装简单,没什么依赖;

2,相比于ab,webbench ,jmeter等工具,wrk 更轻量;

3,学习曲线基本为零,简单了解一下使用参数就可以上手干活了;

4, 基于系统自带的高性能 I/O 机制,如 epoll, kqueue, 利用异步的事件驱动框架,通过很少的线程就可以压出很大的并发量;

5, 支持https (ab、webbench不支持);

6, 可以通过lua脚本定制测试过程,和测试配置,灵活性高。


劣势:

wrk 目前仅支持单机压测,后续也不太可能支持多机器对目标机压测,因为它本身的定位,并不是用来取代 JMeter, LoadRunner 等专业的测试工具,wrk 提供的功能,对我们后端开发人员来说,应付日常接口性能验证还是比较友好的。

总结:

wrk是一个轻量级的性能测试工具,上手简单,非常适合我们开发人员日常开发过程中的压测工作。

安装

注意:wrk 通常用在linux 类环境中,通过命令行操作;所以本文档也仅测试linux。

wrk 官方没有提供release包下载,所以推荐源码安装:

#安装编译环境(如果已经准备过,可以跳过)
sudo yum install -y git make gcc unzip

git clone https://github.com/wg/wrk.git  (或者 https://gitee.com/geekyu/wrk.git )
cd wrk  
make

编译完成后,在当前当前目录下,生成可执行文件 wrk:

可以将该执行文件复制到系统应用目录,即完成安装

sudo cp wrk /usr/sbin/

基本测试

参数解释:

-t 12 : 指明采用12个线程;

-c 200 : 设置整个测试过程,维持200个连接;

-d 30s : 设置整个测试过程,持续30秒钟。

注意: wrk采用的是多路IO复用的模型,所以线程不宜过多(推荐是cpu核数、线程数的2倍即可);过多的线程反而有很大的系统调度开销,极限情况下,影响测试结果。

 

输出结果解释:

12 threads and 200 connections:
总共是12个线程,200个连接(不是一个线程对应一个连接)。


latency和Req/Sec:
代表单个线程的统计数据,latency代表延迟时间,Req/Sec代表单个线程每秒完成的请求数。它们都具有平均值, 标准偏差, 最大值, 正负一个标准差占比。通常,我们关注平均值和最大值;标准差则反应了请求的波动性,在测试负载均衡、缓存命中等有很好的统计参考意义。


14544 requests in 30.09s, 149.58MB read:
在30秒之内总共完成14544个请求,总共读取149.58MB的数据。


Socket errors: connect 0, read 0, write 0, timeout 8
连接统计,有8次超时。


Requests/sec:    483.30

所有线程,平均每秒钟完成483.3个请求(QPS, 通常是反映服务端服务能力的一个重要指标)。


Transfer/sec:      4.97MB

所有线程,平均每秒钟读取4.97MB数据量。

通过脚本定制测试过程

先看一个官方的脚本例子 setup.lua:

-- example script that demonstrates use of setup() to pass
-- data to and from the threads

local counter = 1
local threads = {}

function setup(thread)
   thread:set("id", counter)
   table.insert(threads, thread)
   counter = counter + 1
end

function init(args)
   requests  = 0
   responses = 0

   local msg = "thread %d created"
   print(msg:format(id))
end

function request()
   requests = requests + 1
   return wrk.request()
end

function response(status, headers, body)
   responses = responses + 1
end

function done(summary, latency, requests)
   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

该脚本的用途和执行过程:

1, setup函数,在线程初始化时调用;向该线程运行空间中,添加一个本线程的标识ID;将当前线程object 记录到线程table中;增加线程数目统计。

2,init 函数,在线程执行时调用;初始化线程内request 统计和response统计;并log一下当前执行线程的标识ID。

3, requst函数,每一次请求调用一次,获取默认的请求数据;然后增加一次请求统计。

4, response函数,每次请求应答到来时调用一次;增加一次应答统计。

5, done函数,整个测试过程最后执行一次;输出各个线程的统计数据。

 

使用该脚本执行测试:

关于wrk脚本的生命周期和hook函数说明见官方文档:

wrk/SCRIPTING at master · wg/wrk · GitHub

个人总结而言,wrk脚本的生命周期,可以表示为:

同时,在整个测试过程中,系统提供了一个wrk 的全局对象,可以在hook函数中访问和配置:

// wrk 的默认值,是依据命令行参数的解析而设置的
// 在测试过程中,可以修改其中的内容,而达到全局修改的目的
 wrk = {
    scheme  = "http",
    host    = "localhost",
    port    = nil,
    method  = "GET",
    path    = "/",
    headers = {},
    body    = nil,
    thread  = <userdata>,
  }


// wrk.format 方法,通常在测试流程的request中调用,用于生成一个预设的http请求;
// 为了提高测试效率,在需要动态生成请求或请求内容的测试中,建议在init阶段先预生成所有请求,通过table维护起来
//  测试过程中只需要顺序读取即可,以避免因为本地的逻辑运算,影响测试结果
function wrk.format(method, path, headers, body)

// wrk.lookup 主要用户预先解析服务端地址
// 域名通常存在缓存,如果在init阶段完成域名解析,可以大幅降低测试阶段的域名解析损耗(这个过程可能会很慢,达到秒级)
function wrk.lookup(host, service)

// 测试服务的连通性
function wrk.connect(addr)

 

enjoy!

0条评论
0 / 1000
huskar
18文章数
2粉丝数
huskar
18 文章 | 2 粉丝
原创

wrk - 简单易用的web压测工具

2023-06-14 10:54:17
142
0

简介

wrk 是一款针对 Http/Https 协议的基准测试工具,它能够在单机多核 CPU 的条件下,使用系统自带的高性能 I/O 机制,如 epoll,kqueue 等,通过多线程和事件模式,对目标机器产生大量的负载。

优势:

1,  安装简单,没什么依赖;

2,相比于ab,webbench ,jmeter等工具,wrk 更轻量;

3,学习曲线基本为零,简单了解一下使用参数就可以上手干活了;

4, 基于系统自带的高性能 I/O 机制,如 epoll, kqueue, 利用异步的事件驱动框架,通过很少的线程就可以压出很大的并发量;

5, 支持https (ab、webbench不支持);

6, 可以通过lua脚本定制测试过程,和测试配置,灵活性高。


劣势:

wrk 目前仅支持单机压测,后续也不太可能支持多机器对目标机压测,因为它本身的定位,并不是用来取代 JMeter, LoadRunner 等专业的测试工具,wrk 提供的功能,对我们后端开发人员来说,应付日常接口性能验证还是比较友好的。

总结:

wrk是一个轻量级的性能测试工具,上手简单,非常适合我们开发人员日常开发过程中的压测工作。

安装

注意:wrk 通常用在linux 类环境中,通过命令行操作;所以本文档也仅测试linux。

wrk 官方没有提供release包下载,所以推荐源码安装:

#安装编译环境(如果已经准备过,可以跳过)
sudo yum install -y git make gcc unzip

git clone https://github.com/wg/wrk.git  (或者 https://gitee.com/geekyu/wrk.git )
cd wrk  
make

编译完成后,在当前当前目录下,生成可执行文件 wrk:

可以将该执行文件复制到系统应用目录,即完成安装

sudo cp wrk /usr/sbin/

基本测试

参数解释:

-t 12 : 指明采用12个线程;

-c 200 : 设置整个测试过程,维持200个连接;

-d 30s : 设置整个测试过程,持续30秒钟。

注意: wrk采用的是多路IO复用的模型,所以线程不宜过多(推荐是cpu核数、线程数的2倍即可);过多的线程反而有很大的系统调度开销,极限情况下,影响测试结果。

 

输出结果解释:

12 threads and 200 connections:
总共是12个线程,200个连接(不是一个线程对应一个连接)。


latency和Req/Sec:
代表单个线程的统计数据,latency代表延迟时间,Req/Sec代表单个线程每秒完成的请求数。它们都具有平均值, 标准偏差, 最大值, 正负一个标准差占比。通常,我们关注平均值和最大值;标准差则反应了请求的波动性,在测试负载均衡、缓存命中等有很好的统计参考意义。


14544 requests in 30.09s, 149.58MB read:
在30秒之内总共完成14544个请求,总共读取149.58MB的数据。


Socket errors: connect 0, read 0, write 0, timeout 8
连接统计,有8次超时。


Requests/sec:    483.30

所有线程,平均每秒钟完成483.3个请求(QPS, 通常是反映服务端服务能力的一个重要指标)。


Transfer/sec:      4.97MB

所有线程,平均每秒钟读取4.97MB数据量。

通过脚本定制测试过程

先看一个官方的脚本例子 setup.lua:

-- example script that demonstrates use of setup() to pass
-- data to and from the threads

local counter = 1
local threads = {}

function setup(thread)
   thread:set("id", counter)
   table.insert(threads, thread)
   counter = counter + 1
end

function init(args)
   requests  = 0
   responses = 0

   local msg = "thread %d created"
   print(msg:format(id))
end

function request()
   requests = requests + 1
   return wrk.request()
end

function response(status, headers, body)
   responses = responses + 1
end

function done(summary, latency, requests)
   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

该脚本的用途和执行过程:

1, setup函数,在线程初始化时调用;向该线程运行空间中,添加一个本线程的标识ID;将当前线程object 记录到线程table中;增加线程数目统计。

2,init 函数,在线程执行时调用;初始化线程内request 统计和response统计;并log一下当前执行线程的标识ID。

3, requst函数,每一次请求调用一次,获取默认的请求数据;然后增加一次请求统计。

4, response函数,每次请求应答到来时调用一次;增加一次应答统计。

5, done函数,整个测试过程最后执行一次;输出各个线程的统计数据。

 

使用该脚本执行测试:

关于wrk脚本的生命周期和hook函数说明见官方文档:

wrk/SCRIPTING at master · wg/wrk · GitHub

个人总结而言,wrk脚本的生命周期,可以表示为:

同时,在整个测试过程中,系统提供了一个wrk 的全局对象,可以在hook函数中访问和配置:

// wrk 的默认值,是依据命令行参数的解析而设置的
// 在测试过程中,可以修改其中的内容,而达到全局修改的目的
 wrk = {
    scheme  = "http",
    host    = "localhost",
    port    = nil,
    method  = "GET",
    path    = "/",
    headers = {},
    body    = nil,
    thread  = <userdata>,
  }


// wrk.format 方法,通常在测试流程的request中调用,用于生成一个预设的http请求;
// 为了提高测试效率,在需要动态生成请求或请求内容的测试中,建议在init阶段先预生成所有请求,通过table维护起来
//  测试过程中只需要顺序读取即可,以避免因为本地的逻辑运算,影响测试结果
function wrk.format(method, path, headers, body)

// wrk.lookup 主要用户预先解析服务端地址
// 域名通常存在缓存,如果在init阶段完成域名解析,可以大幅降低测试阶段的域名解析损耗(这个过程可能会很慢,达到秒级)
function wrk.lookup(host, service)

// 测试服务的连通性
function wrk.connect(addr)

 

enjoy!

文章来自个人专栏
后台开发技术分享
18 文章 | 4 订阅
0条评论
0 / 1000
请输入你的评论
1
0