文章

wrk简介与使用备忘

一、什么是wrk

在平时的开发过程中,对于部分业务,我们对其性能具有一定的要求,或者想对其QPS达到多少有一个大概的概念,这时候就需要借助基准测试工具

wrk是一款针对HTTP协议的基准测试工具,具备如下优点:

  1. 轻量级性能测试工具,安装简单
  2. 学习成本低
  3. 基于异步事件驱动框架,单机支持并发高

比较常用的性能测试工具有Apache JMeterApache ab等,但是对于开发人员来说,在不需要如接口串联,场景压测等太多丰富功能的情况下,用JMeter这样的工具过于重了。而相对轻量,简单的选择中,ab的性能和wrk比起来又逊色不少(Nginx官方进行压测时也用wrk,而ab只能使用单核。本身就可能是压测的瓶颈),所以在日常工作中,推荐使用wrk对想要测试的接口进行基准测试

二、安装

因为wrk使用了一些限定于类UNIX操作系统使用的的编程特性,比如epollkqueue等来保证其在低资源占用情况下还能保证如此好的性能,所以我们只能在Linux环境,或者通过在Windows上运行的WSL子系统,虚拟机等环境使用它

通常的网络教程会让我们先从Github上拉取最新的源码,再在自己电脑上进行构建,我们这里直接下载安装别人构建好的最新版:

结合在我们公司经常接触到的Linux环境(CentOS),先下载RPM包,RPM resource wrk ,然后安装:

1
yum install -y ./wrk-4.2.0-1.2.x86_64.rpm

三、使用示例

wrk只占用非常少的资源,

可选参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-c, --connections: total number of HTTP connections to keep open with
                   each thread handling N = connections/threads

-d, --duration:    duration of the test, e.g. 2s, 2m, 2h

-t, --threads:     total number of threads to use

-s, --script:      LuaJIT script, see SCRIPTING

-H, --header:      HTTP header to add to request, e.g. "User-Agent: wrk"

    --latency:     print detailed latency statistics

    --timeout:     record a timeout if a response is not received within
                   this amount of time.

3.1 GET请求

命令示例,这里以携带了一个Authorization头的请求为例:

1
wrk -c12 -t12 -d30s --latency -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXJ2ZXIiOmZhbHNlLCJzdWIiOiIzNzE1NjczMDQ3ODE4OTMiLCJ1c2VyX25hbWUiOiIxODg4ODg4  ODg4OCIsInNjb3BlIjpbInNldmVyIl0sIm5hbWUiOiIxODg4ODg4ODg4OCIsImV4cCI6MTY3NjI1MDU3MiwianRpIjoiOTZkOTNkZjgtZjI1ZS00YTVkLTkyZWMtZmNiNmVhOWQ2ZGIxIiwidGVuYW50IjoidDM3MTY3NzU4OTU5NDI4MCIsI  mNsaWVudF9pZCI6InN5cyJ9.vIhY2tf9uLJepxt5T8EV5DEqgiOL2rhLYl411rQ6qMU" 'http://192.168.100.1:8080/api/iot-device/devicemanage/v1/device/detail?instance=yvS58FQ8&deviceId=ktj10'

3.2 POST请求

要发起POST请求,需要在lua脚本中指定body内容

命令示例:

1
wrk -c100 -t12 -d30s -s wrk.lua http://192.168.100.1:8080/api/script-engine/runner/v1/decode

wrk.lua文件内容:

1
2
3
wrk.method = "POST"
wrk.body = "{\"language\":\"JavaScript\",\"script\":\"business/public/script-engine/debug.js\"}"
wrk.headers["Content-Type"] = "application/json"

四、测试报告

1
2
3
4
5
6
7
8
9
10
11
12
13
Running 30s test @ http://192.168.3.24:8080
  12 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   675.82us  477.60us  21.34ms   89.46%
    Req/Sec    11.62k     0.90k   16.35k    68.86%
  Latency Distribution
     50%  550.00us
     75%  806.00us
     90%    1.14ms
     99%    2.35ms
  4165550 requests in 30.04s, 158.90MB read
Requests/sec: 138683.40
Transfer/sec:      5.29MB

会对测试的延迟分布情况,吞吐量等有一个直观的报告,在这里不多赘述,如图,代表在30秒内完成了4165550次请求,平均每秒138683.40次,并且百分之99以上的请求延迟都在2.35ms以内

五、注意事项

  1. 对比压测结果,记得结合实际运行服务的机器的实际情况,比如测试一个部署在自己电脑上的接口,与测试部署在开发环境的接口,因为电脑的配置不同,通常会有较为明显的差异,不能直接进行比较
  2. 在对开发环境的服务进行压力测试时,建议直接请求服务暴露出来的宿主机端口,而不是经过网关,因为在需要非常高性能的情况下,往往网关是一个不能突破的瓶颈
  3. 若要对开发环境的服务进行压测,请在Rancher上对自己的服务允许使用的最大内存进行预限制,防止因为无限制占用资源影响到整个环境的稳定性

参考资料

本文由作者按照 CC BY 4.0 进行授权