我们有些时候想快速验证我们的解决方案是不是存在性能问题, 或者在并发情况下是否有意想不到的问题. 安装 LoadRunner 这样工具, 录制脚本很麻烦, 用起来就像在用大炮打蚊子.

wrk 是一个比较先进的 HTTP 压力测试工具。wrk负载测试时可以运行在一个或者多核CPU,wrk结合了可伸缩的事件通知系统epoll和kqueue等多线程设计思想。目前wrk可以安装在Linux系统和Mac系统。只有一个命令行, 就能做很多基本的 http 性能测试.

下载源代码

https://github.com/wg/wrk

使用参考

https://www.cnblogs.com/savorboard/p/wrk.html

https://zjumty.iteye.com/blog/2221040  (写的比较好)wrk 提供的几个 lua 的 hook 函数: 

安装参考

[程序员赵鑫] http://www.cnblogs.com/xinzhao/p/6233009.html

 

wrk中的lua脚本(分析lua脚本原理)

例子:表单的提交

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

 

性能测试工具 wrk,ab,locust,Jmeter 压测结果比较(笔记)

线程数不是越高越好

300线程跑60秒:Requests per second=2301.68

500线程跑60秒:Requests per second=2279.27

可见线程数加到500,还不如300的了,所以有时候线程数不是加的越高越好,更根据服务器的配置,CPU,IO,带宽等的消耗设置合理的线程数
细心的读者可能看出,我虽然设置了-t参数为60s,但实际只运行了20多秒,因为ab跑满50000个request就自己停了,想跑够60s可以使用-n参数

wrk指定lua文件发post请求

如果post请求的body不为空则指定lua文件进行读取,示例如下:
./wrk -t 5 -c 300 -d 60 --script=post.lua --latency https://api.midukanshu.com/logstash/userbehavior/create
post.lua文件内容
wrk.method = "POST"
wrk.body = ""
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"

 

性能工具对比笔记

Keith Mo #5 · 2018年08月27日

http_load 06年的过时东西了就别提了吧……

ab不推荐,content-length长度变了也当成错误,而且单线程是个瓶颈,用nginx-status页面做测试,客户端找台8核以上的服务器,跑一下就知道和wrk差距有多大了。

小工具推荐 wrk2,https://github.com/giltene/wrk2,是 wrk 的分支。推荐看看作者 Gil Tene 在 readme 里写的关于如何正确测量响应时间,推荐搜一下作者讲 coordinated omission(CO) 的 2 个youtube视频。

wrk 也可用,性能也更好些。建议跟 wrk2 对照,毕竟CO是个大坑,全世界绝大部分压测工具都掉坑里。

locust (基于python开源)不推荐,一是作者看上去不知道自己在做什么,二是框架性能和报告功能都极差,有这功夫填坑不如找个更正经的框架二次开发。(locust可以和HttpRunner结合实现监控作用。)

ngrinder 不推荐,往往是只做过demo的人才吹它的开箱即用。github上2年多没更新了,跟死了差不多。

taurus + jmeter(基于java开源)组合现在很流行,算是可用,但小心CO问题。它的命令行报告生成的网页里,首页的响应时间百分位数统计不一定可靠,注意点开看菜单里的各种overtime图表。坑踩得少的人很容易用它骗自己接口的响应时间没问题。现在项目里已经基本抛弃它了。

愿意封装和写代码的话推荐 Gatling。动手封装前最好搜一下一篇貌似叫 close workload model vs open workload model 之类的论文,06年的。Gatling 要用 open workload model,也就是指定 RPS 然后它每秒新建这么多连接,才能避免 CO 问题。

wrk摘抄笔记

参考文档   https://testerhome.com/topics/15772?locale=zh-CN

压测线程不宜过多

一般线程数不宜过多,核数的2到4倍足够了,多了反而因为线程切换过多造成效率降低,因为wrk不是使用每个连接一个线程的模型, 而是通过异步网络io提升并发量,所以网络通信不会阻塞线程执行,这也是wrk可以用很少的线程模拟大量网路连接的原因,而现在很多性能工具并没有采用这种方式, 而是采用提高线程数来实现高并发,所以并发量一旦设的很高, 测试机自身压力就很大,测试效果反而下降。

压测结果几个重要指标
一般我们最关心的几个结果指标
1、Latency: 可以理解为响应时间分布。
2、Requests/Sec: 每秒的处理请求数,可以理解为tps。
3、连接超时数目timeout。

高级应用(动态化请求参数):

  • 返回随机的uuid
  • lua计算md5 (需要require lua的md5库函数)

在lua脚本里你可以修改 method, header, body, 可以对 response 做一下自定义的分析。

注意: 一般修改method, header, body不会影响测试端性能, 但是操作 request, response 就要格外谨慎了。

get动态参数

post动态参数

mac 下快捷安装

brew install wrk

liux安装步骤概述

1.git clone下载源代码

2. cd wrk,make

3.make之后,会在项目路径下生成可执行文件wrk,随后就可以用其进行HTTP压测了。

4. cp wrk /usr/local/bin 可以把这个可执行文件拷贝到某个已在path中的路径,比如/usr/local/bin,这样就可以在任何路径直接使用wrk了。

指定LuaJIT和OpenSSL安装

配置修改LuaJIT和OpenSSL(非必须步骤)

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

make WITH_LUAJIT=/usr WITH_OPENSSL=/usr

查看帮助

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

Usage: wrk <options> <url>                            
  Options:                                            
    -c, --connections <N>  Connections to keep open   
    -d, --duration    <T>  Duration of test           
    -t, --threads     <N>  Number of threads to use   
                                                      
    -s, --script      <S>  Load Lua script file       
    -H, --header      <H>  Add header to request      
        --latency          Print latency statistics   
        --timeout     <T>  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 <N>  跟服务器建立并保持的TCP连接数量  
    -d, --duration    <T>  压测时间           
    -t, --threads     <N>  使用多少个线程进行压测   
                                                      
    -s, --script      <S>  指定Lua脚本路径       
    -H, --header      <H>  为每一个HTTP请求添加HTTP头      
        --latency          在压测结束后,打印延迟统计信息   
        --timeout     <T>  超时时间     
    -v, --version          打印正在使用的wrk的详细版本信息
                                                      
  <N>代表数字参数,支持国际单位 (1k, 1M, 1G)
  <T>代表时间参数,支持时间单位 (2s, 2m, 2h)

使用Lua脚本个性化wrk压测

aaa_create.lua文件内容如下

request = function()
    wrk.headers["cookie"] = 'aaaa'; 
    wrk.headers["Content-Type"] = "application/json;charset=UTF-8"
    wrk.headers["x-csrftoken"] = "75wTnK6TL85Nh5Pe0fhVTy8cpZQ"
    wrk.body="{\"type\":1,\"status\":[1],\"from_time\":1546963200,\"to_time\":1547568000}"

   -- Return current request url formated by wrk api
    return wrk.format("POST", "/api/aaatask/create")
end

response = function(status, headers, body)
    if status ~= 200 or string.find(body, "\"retcode\":0") == nil then

        print("error", body)
    else
        print("right", body)
    end
end

done = function(summary, latency, requests)
   print("welcome to wrk!")
end

 

wrk执行命令

wrk -t10 -c10 -d5s  --script=aaa_create.lua --latency https://www.aaa.com

wrk压测结果分析

  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.44s   409.67ms   2.00s    65.79%
    Req/Sec     0.03      0.18     1.00     96.74%
  Latency Distribution
     50%    1.55s 
     75%    1.73s 
     90%    1.89s 
     99%    2.00s 
  92 requests in 5.10s, 329.17KB read
  Socket errors: connect 0, read 0, write 0, timeout 54
Requests/sec:     18.04
Transfer/sec:     64.53KB

 

Logo

更多推荐