wrk是一款开源的高性能http压测工具(也支持https),很是小巧,能够执行文件只有3M(其中主要是luajit和openssl占用绝大多数空间),别看核心代码3-5年没更新了,但依旧很是好用。虽然很早以前我就知道有这么个工具了,当时学习这个工具的时候我还拿它压测了咱们的我的网站xindoo.me,发现mysql性能不行后加了wp-cache,经过cache把我网站的承载能力提高了10多倍。但当时以前简单使用它的初级功能,最近工做中刚好有个http服务须要压测,而后就拿wrk作了。此次使用了wrk lua高级功能实现了压测,咱们找到了咱们服务的瓶颈,同时也被wrk的超高性能所震惊。

如上图,我用单机(40 cores)压90台机器的集群,压到了31w的QPS,最后压不上去不是由于这台机器抗不住了,而是由于咱们服务扛不住了。一个有复杂业务逻辑的服务和一个毫无逻辑的压测相比有失公允,但在压测过程当中我也干垮了4台机器的nginx集群(这里nginx也只是个方向代理而已),这足见wrk性能之高。依赖lua脚本,wrk也能够完成复杂http请求的压测,接下来跟我一块儿了解下wrk的具体使用吧。mysql

wrk的一切内容都在githubhttps://github.com/wg/wrk上,不像其余各类流行的工具包包同样,它并无提供各个平台的可执行包,只有在mac上能够经过brew安装(应该也不是做者提供的)。好在编译wrk并不难,也不须要什么特殊的配置,git clone https://github.com/wg/wrk.git 或从github上直接下载zip包,进入项目目录后直接执行make,你就能够获得一个可执行文件wrk 。nginx

Options:

-c, --connections Connections to keep open # 指定创建多少个网络连接,全部线程复用这些连接

-d, --duration Duration of test # 指定总共起多少个线程

-t, --threads Number of threads to use # 压测持续多长时间

-s, --script Load Lua script file # 指定lua脚本文件,后文会详细介绍

-H, --header Add header to request # 指定http请求的header头

--latency Print latency statistics

--timeout Socket/request timeout

-v, --version Print version details # 输出版本号,经我测试其实是用不了的

wrk这个命令提供的参数也很少,运用这些参数能够一行命令完成一个简单http请求的压测,咱们以国民检测网络状况最经常使用的一个网站为例。git

> ./wrk https://www.baidu.com -c100 -t10 -d100s

Running 20s test @ https://www.baidu.com

10 threads and 100 connections

Thread Stats Avg Stdev Max +/- Stdev

Latency 145.48ms 91.46ms 1.24s 93.71%

Req/Sec 71.11 16.91 144.00 66.95%

14161 requests in 20.09s, 211.91MB read

Socket errors: connect 0, read 137, write 0, timeout 0

Requests/sec: 705.00

Transfer/sec: 10.55MB

经过一行shell命令就能够垂手可得完成对百度首页的压测,但若是你须要压一些复杂的http请求时,指定这些参数明显作不到,这时候就须要wrk的高级功能,经过-s指定lua脚本。 固然lua脚本也不是随便写了就能用的,须要按wrk的规范去写wrk才能正常调用。github

wrk封装了一个http请求的结构,他是经过wrk这个结构体中的内容去完成一次http请求的,因此你想让http请求不一样只须要修改这里面的内容便可,wrk提供了让你修改内容的方法。注意:wrk每一个线程都是单独的lua运行环境,互不干扰,没有交集。若是你想在多线程共享一些数据的话,你能够用table这个全局变量来共享。web

wrk = {

scheme = "http",

host = "localhost",

port = nil,

method = "GET",

path = "/",

headers = {},

body = nil,

thread = ,

}

除了上述结构体外,wrk容许你重写有些给的的function来实现你请求的自定义,如下是其方法名和调用时机。redis

global setup -- 线程启动前调用一次

global init -- 线程启动后调用一次

global delay -- 每次发起一个请求都会调用

global request -- 每发起一个请求前都会调用

global response -- 获取到请求响应结果后调用

global done -- 压测结束后会调用一次

每一个方法都是可选的, 若是你想重定义某个阶段的行为,你能够选择重写该方法,具体方法介绍以下。sql

setup

function setup(thread)是有参数传入的,传入的内容就是当前的线程,setup是在ip地址解析后而且全部线程初始化后,但没用启动前执行的,因此这个时候你能够对thread的构造作一些自定义。shell

thread.addr - 设置当前线程压测的ip,能够指定线程只压测某个ip

thread:get(key) - 读取线程中某个key对应的值,后面能够用key-value执行不一样的逻辑

thread:set(key, value) - 在线程环境中设置一个KV

thread:stop() - 停掉线程,只能在线程还在运行的状况下调用

init

function init(args)是在线程启动后调用,这里是能够传参数的,在启动命令后加-- arg1 arg2,你就能够在init里经过args[1], args[2]获取到arg1和arg2,举例以下。网络

> ./wrk https://www.baidu.com -c100 -t10 -d100s -- 10 20

function init(args)

print(args[1]) -- 输出10

print(args[2]) -- 输出20

end

因此这里能够经过这种方式定义更多的自定义参数,而后经过init(args)作解析,后续能够实现多的功能。多线程

delay

function delay()就很简单了,它是为了让你去控制请求发送的之间间隔,若是你想隔10ms发送一次请求,直接return 10就好了,经过delay()能够实现qps大小的控制。

request()

function request()主要功能是为了定制每次请求的参数数据,若是你想构造一些复杂的请求,request()是不得不改的,你能够再request()中修改上文wrk 结构体中的全部值,基本上最长改动的就是wrk.header, wrk.path, wrk.body。这里须要注意,request()是要求有返回值的,其返回值是wrk.format(method, path, headers, body),wrk.format会将这些参数构形成一个http请求可用的请求数据。

response

function response(status, headers, body)是在每次wrk收到http请求响应后调用,wrk会将请求响应中的http status、headers和body做为参数传递进来,你能够经过这些参数信息作响应统计、调整压测流量、甚至中止压测……等比较自动化的操做。

done

function done(summary, latency, requests)是在压测结束后wrk会调用一次,即使有多个线程也只调用一次。wrk会将压测过程当中的统计信息经过参数传递给你,你能够挑其中有用的部分输出。也能够输出你在response()中自行统计的内容。

wrk已经为你提供了如下的统计信息:

latency.min -- 最小延迟

latency.max -- 最大延迟

latency.mean -- 平均延迟

latency.stdev -- 延迟的标准差

latency:percentile(99.0) -- 99分位的延迟

latency(i) -- raw value and count

summary = {

duration = N, -- 运行的时间ms

requests = N, -- 总请求数

bytes = N, -- 总过收到的字节数

errors = {

connect = N, -- 连接错误数

read = N, -- socket数据读取出错数量

write = N, -- socket数据写入出错数量

status = N, -- http code 大于399的数量

timeout = N -- 超时请求的总数量

}

}

流量控制方法

wrk使用了多路复用的技术。多路复用使得用一个线程能够异步发起不少个请求,因此不太好用线程数来控制请求数。但一个http链接同时只能处理一个请求,因此能够按一次请求的latency估算出一个链接能够承载的qps数,调整链接数便可控制压测请求大小qps = 1000/latency * Connectnum。 这里须要注意的是单个线程只能占用一个cpu核心,当cpu到瓶颈时也可能压不上去,须要调整线程数。

另一个方法,把链接数设置的很是大,让链接数再也不是发压的瓶颈,而后调整脚本中的delayTime和线程数,能够精确控制qps。 qps = 1000/delayTime * threadnum

总结

在实际压测过程当中,我曾用一个线程压出过几十万qps,也好奇过为何一个线程能压出这么高的qps。咱们每次请求须要5ms,因此按道理一个线程只能压出200qps,那实际上几百倍的差别是如何来的?后来大体了解到wrk的做者使用了多路复用的技术(epoll,kqueue),每次请求后并非阻塞等在在那里,并且异步等待结果,同时也能够发起下一个请求,这和redis很像吧,其实wrk的做者代码都是抄的redis的,哈哈。

因此这里要注意-c和-t链接数和参数的设置,一个线程只能占用一个cpu核,若是还没到cpu的瓶颈,决定qps的是链接处和瓶颈响应时间,举个例子,若是只有一个线程,连接数10,平均响应时间10ms,那么一个连接一秒能过100个请求,因此总共能压出1000qps。当cpu到瓶颈后,无论怎么去调大链接数qps都不会上去,这个时候就须要考虑调大线程数了,利用多核心的资源提高qps。

最后附上咱们压测中实际使用的lua脚本,结构也比较简单,你们能够大体参考下。

local list = {}

local delaytime = 0 -- 默认delay是0ms

local filename = "reqdata.txt" -- 默认请求数据文件

setup = function(thread)

for k,v in pairs(wrk.addrs)

do

print(v)

end

end

init = function(args)

if (args[1] ~= nil) then

delaytime = args[1] -- 启动命令中能够指定延迟时间,如未指定,使用默认文件

end

if (args[2] ~= nil) then

filename = args[2] -- 启动命令中能够指定请求文件目录,如未指定,使用默认文件

end

math.randomseed(os.time())

local i = 0

for line in io.lines(filename) -- 把请求包体读入后写到list里,方便后续使用

do

list[i] = line

i = i+1

end

end

request = function()

wrk.body = list[math.random(0, #list)] -- 随机使用一个包体

wrk.method = "POST"

wrk.scheme = "http"

wrk.path = "/appstore/uploadLogSDK"

wrk.headers["Content-Type"]="application/x-www-form-urlencoded"

return wrk.format()

end

delay = function()

return delaytime

end

response = function(status, headers, body) --这里我没作特殊统计,只是在调试过程当中输出了一些内容

--print(status)

--print(body)

--print(wrk.format(wrk.method, wrk.path, wrk.headers, wrk.body))

--wrk.thread:stop()

end

done = function(summary, latency, requests)

print("99 latency:"..latency:percentile(99.0)) -- 这里我只是额外输出了99分位的延时,貌似数据不太对

end

web版本 开源压测工具_Web服务压测神器wrk相关推荐

  1. web版本 开源压测工具_Web压测工具之Webbench和http_load

    Webbench简介 是知名的网站压力测试工具,能测试处在相同硬件上,不同服务的性能以及不同硬件上同一个服务的运行状况. webbench的标准测试可以向我们展示服务器的两项内容:每秒钟相应请求数和每 ...

  2. web版本 开源压测工具_免费压测工具

    很多的web应用在搭建服务器完成后,为了让搭建的服务能够满足用户的访问需求,通常需要测试自己应用的并发连接能力.需要使用一些压测工具,本文介绍一些免费的开源的压测工具,可以用于简单的压力测试(实验均在 ...

  3. linux tcp压测工具,02.监控和压测工具 - 2.4.压测工具 - 《Linux性能调优指南》 - 书栈网 · BookStack...

    压测工具其它有用工具 在这里,我们会讨论主要的压力测试工具,选择合适的压测工具,才能准确衡量系统性能.好的压测工具有很多,可能的功能如下: 发起压力 监控性能 监控系统使用率 生成报告 基准测试无非就 ...

  4. python 压测工具_流量压测工具 | 亚马逊AWS官方博客

    (可用于测试AWS ELB.EC2.Auto Scaling.HA) 一群勤劳的小蜜蜂 很多时候我们需要进行负载均衡.Web服务器的并发式压力测试,但像Siege, JMeter等工具都是从一个源IP ...

  5. web版本 开源压测工具_开源了一个简单的http服务压测工具Alex,自带web ui,golang实现...

    Alex是基于vegeta library和boom封装的压力测试web UI.Vegeta提供稳定的qps压力源,boom提供稳定的并发数压力源. github地址 https://github.c ...

  6. web版本 开源压测工具_标星 1.3K 的 Web 框架压测库,助你更好的选择框架

    大家好,我是你们的章鱼猫. 目前开源界有很多的 Web 框架,而一款好的 Web 框架能够给你在开发效率和后期维护上减少很多不必要的麻烦.所以在项目初期选择一款好的 Web 框架至关重要. 在 Go ...

  7. web版本 开源压测工具_14款好用开源的Web应用压力负载,性能测试工具推荐

    JMeter JMeter是Apache组织的开放源代码项目,它是功能和性能测试的工具,100%的用java实现. Grinder Grinder是一个负载测试框架,通过Jython来编写测试脚本,基 ...

  8. web版本 开源压测工具_siege--Web性能压测工具

    -V, --version    VERSION, prints the version number. -h, --help    HELP, prints this section. -C, -- ...

  9. 2022年6月最新的青龙面板2.12+版本CK上传工具Ninja面板,亲测升级到最新的2.13.3也是正常使用

    我自己搭建的面板上车点链接跳转,防止wsck泄露只支持ck登录可能需要一个月更新一次ck望周知 群通知目前只有钉钉,上车的点击麻烦加一下群 我修改的ninja面板github仓库 目前主要是CK能上传 ...

最新文章

  1. OpenCV代码提取:Windows上通过DShow获取Camera视频
  2. keras中重要的函数用法及参数详解
  3. 【解析】1012 The Best Rank (25 分)
  4. 等压线上怎么画风向_战场上骑兵应该怎么拔刀?从清人佩刀为何总是刀柄向后说起...
  5. ios 裁剪圆形头像_IOS_iOS如何裁剪圆形头像,本文实例为大家介绍了iOS裁剪 - phpStudy...
  6. Android Picasso最详细的使用指南
  7. android融云自定义消息界面大小,融云自定义消息通知栏显示
  8. 解决cacti创建ping主机时不出图的问题
  9. 编码优先级表达的严重性
  10. 如何自定义cad线型_百度经验.html,如何找到自己需要的CAD线型?教你怎样自定义CAD线型...
  11. 小米路由器4a开发版固件_小米路由器4a刷第三方固件
  12. C++:Trivial、Standard-Layout 和 POD
  13. 上偏续关系哈斯图_[离散]哈斯图偏序集--最好理解版本
  14. 为什么我不建议你轻易入上位机的“坑”?
  15. 拼多多商家后台字体加密分析
  16. 氟胶耐腐蚀油罐泵出口应用性能
  17. ASP.NET动态网站开发培训-23.论文管理系统(三、制作论文内容页面)
  18. 昱章电气在科创板IPO终止:曾计划募资约5亿元,客户集中度较高
  19. python入门:缺省函数
  20. 如何用python爬虫爬取qq空间说说

热门文章

  1. 不格式化磁盘,怎么对Win11、Win7分区?
  2. 外行对程序员的误解到底有多深?来看你有没有中招
  3. 《华为C语言编程规范 》笔记
  4. 本“徕”就美,Xiaomi 12S 系列原生双画质的修炼秘籍
  5. 无线传感器网络:数据链路层,MAC
  6. 从零开始实现C++ TinyWebServer 全过程记录
  7. scroll-view 开启自定义下拉刷新 scroll-view里面内容太少无法触发刷新
  8. ADAMS/MATLAB联合仿真机械臂重力补偿问题
  9. Hive数据定义语言DDL
  10. 想创业先问自己20个问题