• wrk HTTP打流测试工具


    1、介绍

    官方解释 wrk is a modern HTTP benchmarking tool capable of generating significant load when run on a single multi-core CPU. It combines a multithreaded design with scalable event notification systems such as epoll and kqueue.

    它结合了多线程以及类似epoll、kqueue的多事件模式,可以在单机多核CPU的条件下构造大量的负载。

    wrk 是一个能够在单个多核 CPU 上产生显著负载的 HTTP 基准测试工具。它采用了多线程设计,能够在单机多核 CPU 的条件下,使用系统自带的高性能 I/O 机制,如 epoll,kqueue 可扩展事件通知机制等,通过多线程和事件模式,对目标机器产生大量的负载。此外,用户可以指定 LuaJIT 脚本来完成 HTTP 请求生成、响应处理和自定义报告等功能。

    2、wrk官网

    GitHub - wg/wrk: Modern HTTP benchmarking tool

    3、优劣

    工具优点        劣点
    wrk

    wrk的优势主要有以下几点:

    • 轻量级的性能测试工具
    • 安装简单(git clone即可)
    • 学习简单,稍微看看文档就可以直接上手
    • 基于系统自带的高性能I/O机制,利用异步的事件驱动框架,通过很少的线程可以压出跟大的并发量(对于测试宿主机几乎无cpu的压力)
    目前支持单机压测,即不支持多机器对目标的压测,即每次压测的机器地址很难去改变,可以改变压测的接口地址,但是压测的机器地址变不了
    curl loader

    curl loader使用的是真正的C编写的客户端协议栈,即基于 libcurl 的 HTTP和FTP协议和 基于 openSSL 的 TLS/SSL,并模拟用户行为,支持登录和身份验证。

    4、wrk 安装

    git clone https://gitee.com/mirrors/wrk.git

    wrk 只能被安装在类 Unix 系统上,所以我们需要一个 Linux 或者 MacOS 环境。Windows 10 安装需要开启自带的 Ubuntu 子系统。

    4.1 Linux 安装

    4.1.1 Ubuntu/Debian

    依次执行如下命令:

    1. sudo apt-get install build-essential libssl-dev git -y
    2. git clone https://github.com/wg/wrk.git wrk
    3. cd wrk
    4. make
    5. # 将可执行文件移动到 /usr/local/bin 位置
    6. sudo cp wrk /usr/local/bin

    4.1.2 CentOS / RedHat / Fedora

    依次执行如下命令:

    1. sudo yum groupinstall 'Development Tools'
    2. sudo yum install -y openssl-devel git
    3. git clone https://github.com/wg/wrk.git wrk
    4. cd wrk
    5. make
    6. # 将可执行文件移动到 /usr/local/bin 位置
    7. sudo cp wrk /usr/local/bin

    5、基础用法

    5.1 【基本参数】

    1. -c, --connections Connections to keep open,需要模拟的连接数
    2. -d, --duration Duration of test,测试的持续时间
    3. -t, --threads Number of threads to use,需要模拟的线程数
    4. -s, --script Load Lua script file,lua脚本,使用方法往下看
    5. -H, --header Add header to request,添加http header, 比如. “User-Agent: wrk”
    6. --latency Print latency statistics,显示延迟统计
    7. --timeout, -T: Socket/request timeout,超时的时间
    8. -v, --version Print version details
    9. 代表数字参数,支持国际单位 (1k, 1M, 1G)
    10. 代表时间参数,支持时间单位 (2s, 2m, 2h)

    5.2 测试报告

    wrk -c 10000 -t 100 http://127.0.0.1:80/test -d 20s -T2 --latency

    1. Running 20s test @ http://127.0.0.1/test
    2. 100 threads and 10000 connections
    3. Thread Stats Avg Stdev Max +/- Stdev
    4. Latency 146.36ms 253.95ms 2.00s 88.39%
    5. Req/Sec 1.24k 298.79 3.61k 69.12%
    6. Latency Distribution
    7. 50% 34.30ms
    8. 75% 176.93ms
    9. 90% 459.42ms
    10. 99% 1.16s
    11. 2484504 requests in 20.10s, 781.90MB read
    12. Socket errors: connect 0, read 0, write 0, timeout 9316
    13. Requests/sec: 123612.53
    14. Transfer/sec: 38.90MB

    我们来具体说一说,报告中各项指标都代表什么意思:

    1. Running 30s test @ http://www.baidu.com (压测时间30s)
    2. 12 threads and 400 connections (共12个测试线程,400个连接)
    3. (平均值) (标准差) (最大值)(正负一个标准差所占比例)
    4. Thread Stats Avg Stdev Max +/- Stdev
    5. (延迟)
    6. Latency 386.32ms 380.75ms 2.00s 86.66%
    7. (每秒请求数)
    8. Req/Sec 17.06 13.91 252.00 87.89%
    9. Latency Distribution (延迟分布)
    10. 50% 218.31ms
    11. 75% 520.60ms
    12. 90% 955.08ms
    13. 99% 1.93s
    14. 4922 requests in 30.06s, 73.86MB read (30.06s内处理了4922个请求,耗费流量73.86MB)
    15. Socket errors: connect 0, read 0, write 0, timeout 311 (发生错误数)
    16. Requests/sec: 163.76 (QPS 163.76,即平均每秒处理请求数为163.76)
    17. Transfer/sec: 2.46MB (平均每秒流量2.46MB)

    5.3 使用 Lua 脚本进行复杂测试

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

    1. 编写lua脚本,填写post的数据, 如 post.lua

    • 单纯的利用POST提交方法
    1. wrk.method = "POST"
    2. wrk.body = "name=zhangsan&password=123456"
    3. wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"

    或者可以采用以下的方式:

    1. wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
    2. request = function()
    3. method = "POST"
    4. body = "name=zhangsan&password=123456"
    5. path = "/user/login" return wrk.format(method,path,nil,body)
    6. end
    • 自定义请求和参数

    要求每一次的参数不同如何处理       

    1. request = function()
    2. uid = math.random(1,1000000)
    3. path = "/login?uid"..uid return wrk.formate(nil,path,nil,nil)
    4. end
    •  设置延迟
    1. function
    2. delay()
    3. return 10 -- 表示设置10ms的延迟 end 
    • 先登录后请求

    这个地方是为了对一些需要先登录获取token,后续的请求都需要携带token请求的接口进行测试的,参照官方给出的lua脚本案例:auth.lua

    1. -- example script that demonstrates response handling and
    2. -- retrieving an authentication token to set on all future
    3. -- requests
    4. token = nil
    5. path = "/authenticate" -- 初始的请求url
    6. request = function()
    7. return wrk.format("GET", path) -- 发送第一次authenticate认证请求
    8. end
    9. response = function(status, headers, body)
    10. if not token and status == 200 then
    11. token = headers["X-Token"]
    12. path = "/resource" -- 拿到之后做修改
    13. wrk.headers["X-Token"] = token -- 修改头,携带token进入后续的请求
    14. end
    15. end
    • pipeline请求

    即一次发送多个请求,参照官方给出的pipeline.lua

    1. -- example script demonstrating HTTP pipelining
    2. init = function(args)
    3. local r = {}
    4. r[1] = wrk.format(nil, "/?foo")
    5. r[2] = wrk.format(nil, "/?bar")
    6. r[3] = wrk.format(nil, "/?baz")
    7. req = table.concat(r)
    8. end
    9. request = function()
    10. return req
    11. end

    2. 执行wrk,开始压力测试

    wrk -t 32 -c 400 -d 10s --timeout 1s -s post.lua http://10.132.237.12:10521/single_p

  • 相关阅读:
    【大数据Hive】hive select 语法使用详解
    HK32F030MF4P6 3路ADC采集
    基于安卓android微信小程序的快递取件及上门服务系统
    SpringMVC之入门
    【C++】类和对象(上篇)(万字)
    自动驾驶学习笔记(五)——绕行距离调试
    SQLAlchemy学习-5.relationship之backref和back_populates参数
    训练营第三十三天贪心(第五部分重叠区间问题)
    Golang数组:全面指南与实际示例
    计算机网络:信道划分介质访问控制
  • 原文地址:https://blog.csdn.net/Kingairy/article/details/133901123