wrk压测工具实操汇总#本地压测工具

价值说明: 利用wrk 2分钟知晓你新开发的接口的基本性能


一、简介

        wrk是一个开源的、热门的、现代的单机HTTP基准测试工具。它能够在单机多核 CPU 的条件下,使用系统自带的高性能 I/O 机制,如 epoll,kqueue 等,通过多线程和事件模式,对目标机器产生大量的负载。

            PS: 其实,wrk 是复用了 redis 的 ae 异步事件驱动框架,准确来说 ae 事件驱动框架并不是 redis 发明的, 它来至于 Tcl 的解释器 jim, 这个小巧高效的框架, 因为被 redis 采用而被大家所熟知。

            并且内置了一个可选的Lua  JIT脚本执行引擎,可以处理复杂的HTTP请求生成、响应处理以及自定义压测报告。


二、跟其他压测工具优缺点对比

一些常用的性能测试工具,如 Apache ab,  Apache JMeter (互联网公司用的较多),LoadRunner 等。

wrk 的优势:

    *轻量级性能测试工具; wrk的结果相比ab测试结果来说,多了一个延时直方图,有了这个直方图,我们可以更清晰的看到延迟的分布情况。这也是博主选择wrk最重要的原因

    * 安装简单(相对 Apache ab 来说);

    * 学习曲线基本为零,几分钟就能学会咋用了;

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

劣势

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

结论:应付日常接口性能验证还是比较友好的


三、Mac上安装

先安装Homebrew,安装方式参考官网 https://brew.sh

也可以执行下面命令  一键安装  > /bin/bash -c "$(curl -fsSLhttps://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

安装wrk:  >  brew install wrk

验证是否安装成功

> wrk -v



四、常用命令、注释和结果分析

命令:  > wrk -t12 -c400 -d30shttp://www.baidu.com

        这条命令表示,利用 wrk 对 www.baidu.com 发起压力测试,线程数为 12,模拟 400 个并发请求,持续 30 秒。

详细参数含义解析

        常用指令说明

                -c, --connections: 要保持打开的HTTP连接的总数,每个线程处理数N =连接/线程

                -d, --duration:    测试持续时间, 如 2s, 2m, 2h

                -t, --threads:    测试线程总数

                -s, --script:      指定加载lua测试扩展脚本

                -H, --header:      添加请求头信息, 如"User-Agent: wrk"

                  --latency:    打印延迟直方图信息

                  --timeout:    如果在此时间内没有收到响应,则记录超时.

                                -开头的指令为简写的,后面两个打印延迟直方图和超时设置没有简写的,只能--开头指定

    命令行中输入 wrk --help, 可以看到支持以下子命令:

结果分析:



五、Get请求如何进行压测

-- 测试指令:wrk -t16 -c100 -d5s -s review_digress_list.lua --latency htt://127.0.0.1:8081

wrk.method ="GET" 

wrk.path = "/app/{appId}/review_digress_list"

 function request() 

         -- 动态生成每个请求的url 

         local requestPath = string.gsub(wrk.path,"{appId}",math.random(1,10)) 

         -- 返回请求的完整字符串:http://127.0.0.1//app/666/review_digress_list 

         return wrk.format(nil, requestPath) 

end


六、Post请求如何进行压测

6.1、Post请求

wrk默认是采用GET请求方式进行接口测试,如果需要使用POST请求就需要使用到lua脚本,通过加载编写好的lua脚本来进行定制化的请求。采用-s 或者 --script可以加载脚本文件。

wrk的请求构造过程主要是针对每一个线程的,所以对于压测的环境也提供了一些函数方法来进行支持线程的环境定制化。

对于POST请求+入参不一致的解决:

对于这种需求,我们可以通过编写 Lua 脚本的方式,在运行压测命令时,通过参数 --script 来指定 Lua 脚本,来满足个性化需求。

wrk 对 Lua 脚本的支持

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

        启动阶段

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

        运行阶段

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

               * delay(): 在每次发送请求之前调用,如果需要定制延迟时间,可以在这个方法中设置;

               * request(): 用来生成请求,每一次请求都会调用该方法,所以注意不要在该方法中做耗时的操作;

               * response(status, headers, body): 在每次收到一个响应时被调用,为提升性能,如果没有定义该方法,那么wrk不会解析 headers 和 body;

       结束阶段

               done() 方法在整个测试过程中只会被调用一次,我们可以从给定的参数中,获取压测结果,生成定制化的测试报告。

6.2、lua脚本

首先下载lua脚本 把接口+入参替换为对应值

-- example script that demonstratesuseof setup() to pass-- data toandfrom the threadslocalcounter =1localthreads = {}function setup(thread)thread:set("id", counter) -- 设置线程id table.insert(threads, thread) -- 用threads的表格存储counter = counter +1-- 为避免id相同,使用counter来实现递增endfunction init(args) -- 注意init中初始化的值都是针对一个线程而言的!即每个线程都是隔离的requests =0-- 初始化,注意这里的初始化的变量都将成为wrk的全局变量,即后续可以直接用responses =0localmsg ="thread %d created"print(msg:format(id))end-- 全局设定 设置请求格式--wrk.method ="POST"--wrk.body ="name=zhangsan&password=123456"wrk.headers["Content-Type"] ="application/json"wrk.headers["Accept"] ="*/*"wrk.headers["Accept-Encoding"] ="gzip, deflate, br"request = function()requests = requests +1-- 构造请求数,因为init中定义了,所以这里可以直接使用uid = math.random(1,10000000)method ="POST"path ="/personal/bill/queryBillDeductDetailAll"body = string.format("uid=%s&serialNo=%s&version=%s&lastId=%s",uid,20220920000108360706,519,0)returnwrk.format(method,path,nil,body)end--function request()-- requests = requests +1-- 构造请求数,因为init中定义了,所以这里可以直接使用--returnwrk.request()--endfunction response(status, headers, body)responses = responses +1-- 获取响应数,因为init中定义了,所以可以直接使用endfunction done(summary, latency, requests)forindex, thread in ipairs(threads)dolocalid = thread:get("id") -- 获取线程idlocalrequests = thread:get("requests") -- 获取构造请求数localresponses = thread:get("responses") -- 获取响应数localmsg ="thread %d made %d requests and got %d responses"print(msg:format(id, requests, responses)) endend

然后控制台输入如下命令(需要修改ip地址)

wrk -t32 -c400 -d30s -s setup.lua --latency htt://10.72.240.219:8888



七、小技巧

    如何将某个参数变成随机参数

        -- 动态生成每个请求的url

        local requestPath =string.gsub(wrk.path,"{appId}",math.random(1,10))

                    -- 返回请求的完整字符串:http://127.0.0.1//app/666/review_digress_list

        return wrk.format(nil, requestPath)

命令行里打印日志

    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))


八、注意事项

        wrk本身不是依赖线程数来模拟并发数的所以线程数量设置在核心数左右最好,线程数多了测试系统消耗大,可能带来反效果。之前测试跟核心数一致的线程数和两倍核心数的线程数,前者压出的QPS更高。

            特别提醒:关于线程数,并不是设置的越大,压测效果越好,线程设置过大,反而会导致线程切换过于频繁,效果降低,一般来说,推荐设置成压测机器 CPU 核心数的 2 倍到 4 倍就行了。


有问题欢迎随时交流

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351

推荐阅读更多精彩内容