这2个性能压测及可视化监控工具,小众但好用!

在api上线之前,我们需要知道API的性能,以便能够了解到API服务器能够承载的最大请求量,性能瓶颈,然后根据业务的要求,对api进行性能调优与扩缩容。

用来衡量API性能的指标主要有3个

  • 并发数(concurrent):在某个时间段内,同时请求同一个API的用户个数。

  • 每秒查询数(QPS):QPS是一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。QPS = 并发数 / 平均请求响应时间

  • 请求响应时间(TTLB):客户端发起请求到得到响应的整个时间。

这三者之中,最重要的是QPS,但是在说明QPS的时候,需要指定是多少并发数下的QPS,否则意义不大。在QPS相同的情况下,并发数越大说明API性能越好,并发处理能力越强。

有很多web性能测试工具,常用的有 Jmeter、AB、Webbench 和 wrk。这里我们使用wrk作为性能测试工具,gnuplot工具来将测试数据以图表的形式展示。

我们以最简单的echo服务器为例来进行性能测试

  1. package main

  2. import (

  3. "log"

  4. "net/http"

  5. )

  6. func main() {

  7. http.HandleFunc("/echo", echo)

  8. log.Fatal(http.ListenAndServe(":8080", nil))

  9. }

  10. func echo(w http.ResponseWriter, r *http.Request) {

  11. q := r.URL.RawQuery

  12. w.Write([]byte(q))

  13. }

wrk使用

首先需要安装wrk

  1. # 下载源码

  2. git clone https://github.com/wg/wrk

  3. cd wrk

  4. # 编译

  5. make

  6. # 可执行文件移动到bin目录下

  7. cp ./wrk /usr/local/bin/

wrk的使用并不复杂,参数也并不多,输入wrk命令就可以看到所有的参数了

  1. $ wrk

  2. Usage: wrk <options> <url>

  3. Options:

  4. -c, --connections <N> Connections to keep open

  5. -d, --duration <T> Duration of test

  6. -t, --threads <N> Number of threads to use

  7. -s, --script <S> Load Lua script file

  8. -H, --header <H> Add header to request

  9. --latency Print latency statistics

  10. --timeout <T> Socket/request timeout

  11. -v, --version Print version details

  12. Numeric arguments may include a SI unit (1k, 1M, 1G)

  13. Time arguments may include a time unit (2s, 2m, 2h)

参数说明:

  • -c:并发数

  • -d:测试的持续时间,默认为10s

  • -t:线程数。(不要太多,为核数的2到4倍即可,太多反而会因为切换过于频繁而降低效率)

  • -T:请求超时时间

  • -H:指定请求的http header。

  • --latency:打印响应时间分布

  • -s:指定lua脚本

启动echo服务程序,执行下面的命令来进行性能测试

  1. wrk -t8 -c10000 -d20s -T20s --latency http://localhost:8080/echo?hello

  2. Running 20s test @ http://localhost:8080/echo?hello

  3. 8 threads and 10000 connections

  4. Thread Stats Avg Stdev Max +/- Stdev

  5. Latency 54.00ms 36.72ms 530.63ms 76.74%

  6. Req/Sec 23.94k 4.89k 39.35k 67.50%

  7. Latency Distribution

  8. 50% 50.78ms

  9. 75% 62.96ms

  10. 90% 90.13ms

  11. 99% 198.25ms

  12. 3789262 requests in 20.09s, 437.26MB read

  13. Requests/sec: 188579.15

  14. Transfer/sec: 21.76MB

用8个线程模拟10000个连接,持续20s进行测试。对于测试的结果,我们需要了解其含义。

  • Thread Stats是线程统计,包括Latency和Req/Sec两部分。

  • Latency:响应时间。有平均值,标准差,最大值,正负偏差在一个标准差范围内的占比。

  • Req/Sec:每个线程每秒完成的请求数,同样有上面的四个值。

  • Latency Distribution响应时间分布

  • 50%:50%的请求响应时间不超过50.78ms

  • 75%:75%的请求响应时间不超过62.96ms

  • 90%:90%的请求响应时间不超过90.13ms

  • 99%:99%的请求响应时间不超过198.25ms

  • 789262 requests in 20.09s, 437.26MB read:表示在20.09s内完成的总请求数为3789262,数据读取量为437.26MB

  • Requests/sec:QPS

  • Transfer/sec:平均每秒读取的数据量(吞吐量)

如果我们将模拟的并发数调大一些,可能还会看到一组数据Socket errors: connect 21774, read 0, write 0, timeout 0:错误统计。包括连接失败请求个数,读失败请求个数,写失败请求个数,超时请求个数。

数据可视化

了解了wrk工具的使用,我们就可以不断调整并发数,然后执行wrk测试命令,将测试的结果使用awk提取出我们想要的指标,比如前文提到的并发数,QPS、TTLB等,然后输出到数据文件当中。

使用gnuplot来从数据文件中获取数据并绘制成图片。

首先,我们安装gnuplot工具

$ sudo yum -y install gnuplot

然后我们编写脚本来完成性能测试的数据收集以及图片的绘制。

先完成整体的框架

  1. # wrk性能测试所用参数

  2. duration="20s"

  3. concurrent="200 500 1000 3000 5000 10000 15000 20000 25000 50000"

  4. threads=$((2 * `grep -c processor /proc/cpuinfo`))

  5. cmd="wrk -t${threads} -d${duration} -T30s --latency"

  6. wrkdir="./wrk"

  7. mkdir -p ${wrkdir}

  8. # 生成的文件名

  9. qpsttlb="echo_qps_ttlb.png"

  10. successrate="echo_successrate.png"

  11. datfile="echo.dat"

  12. # 性能测试流程

  13. for c in ${concurrent}

  14. do

  15. wrkcmd="${cmd} -c ${c} $1"

  16. echo "Running wrk command: ${wrkcmd}"

  17. result=`eval ${wrkcmd}` # 执行性能测试命令并获取结果

  18. convert_plot_data "${result}" # 从结果中提取数据并保存为数据文件

  19. done

  20. plot &> /dev/null #根据数据文件绘制出图片

剩下就是两个函数了,首先是负责生成数据文件的convert_plot_data函数​​​​​​​

  1. function convert_plot_data()

  2. {

  3. # 传入wrk性能测试的执行结果,提取出需要的信息,写入文件当中

  4. echo "$1" | awk -v datfile="${wrkdir}/${datfile}" ' {

  5. if ($0 ~ "Running") {

  6. common_time=$2

  7. }

  8. if ($0 ~ "connections") {

  9. connections=$4

  10. common_threads=$1

  11. }

  12. if ($0 ~ "Latency ") {

  13. avg_latency=convertLatency($2)

  14. }

  15. if ($0 ~ "50%") {

  16. p50=convertLatency($2)

  17. }

  18. if ($0 ~ "75%") {

  19. p75=convertLatency($2)

  20. }

  21. if ($0 ~ "90%") {

  22. p90=convertLatency($2)

  23. }

  24. if ($0 ~ "99%") {

  25. p99=convertLatency($2)

  26. }

  27. if ($0 ~ "Requests/sec") {

  28. qps=$2

  29. }

  30. if ($0 ~ "requests in") {

  31. allrequest=$1

  32. }

  33. if ($0 ~ "Socket errors") {

  34. err=$4+$6+$8+$10

  35. }

  36. }

  37. END {

  38. rate=sprintf("%.2f", (allrequest-err)*100/allrequest)

  39. print connections,qps,avg_latency,rate >> datfile

  40. }

  41. function convertLatency(s) {

  42. if (s ~ "us") {

  43. sub("us", "", s)

  44. return s/1000

  45. }

  46. if (s ~ "ms") {

  47. sub("ms", "", s)

  48. return s

  49. }

  50. if (s ~ "s") {

  51. sub("s", "", s)

  52. return s * 1000

  53. }

  54. }'

  55. }

可以看到在print connections,qps,avg_latency,rate >> datfile中将指标写入数据文件。

另外一个就是负责绘图的plot函数了​​​​​​​

  1. function plot() {

  2. gnuplot << EOF

  3. set terminal png enhanced #输出格式为png文件

  4. set ylabel 'QPS'

  5. set xlabel 'Concurrent'

  6. set y2label 'Average Latency (ms)'

  7. set key top left vertical noreverse spacing 1.2 box

  8. set tics out nomirror

  9. set border 3 front

  10. set style line 1 linecolor rgb '#00ff00' linewidth 2 linetype 3 pointtype 2

  11. set style line 2 linecolor rgb '#ff0000' linewidth 1 linetype 3 pointtype 2

  12. set style data linespoints

  13. set grid #显示网格

  14. set xtics nomirror rotate #by 90#只需要一个x轴

  15. set mxtics 5

  16. set mytics 5 #可以增加分刻度

  17. set ytics nomirror

  18. set y2tics

  19. set autoscale y

  20. set autoscale y2

  21. set output "${wrkdir}/${qpsttlb}" #指定数据文件名称

  22. set title "QPS & TTLB\nRunning: ${duration}\nThreads: ${threads}"

  23. plot "${wrkdir}/${datfile}" using 2:xticlabels(1) w lp pt 7 ps 1 lc rgbcolor "#EE0000" axis x1y1 t "QPS","${wrkdir}/${datfile}" using 3:xticlabels(1) w lp pt 5 ps 1 lc rgbcolor "#0000CD" axis x2y2 t "Avg Latency (ms)"

  24. unset y2tics

  25. unset y2label

  26. set ylabel 'Success Rate'

  27. set ytics nomirror

  28. set yrange[0:100]

  29. set output "${wrkdir}/${successrate}" #指定数据文件名称

  30. set title "Success Rate\nRunning: ${duration}\nThreads: ${threads}"

  31. plot "${wrkdir}/${datfile}" using 4:xticlabels(1) w lp pt 7 ps 1 lc rgbcolor "#F62817" t "Success Rate"

  32. EOF

  33. }

有关gnuplot的使用这里就不过多介绍了,后续可能会专门开启一章进行学习,上面的内容虽然看着复杂,但是总体上就是两个部分:

  • 1.设置图片坐标轴的基本信息,以及样式

  • 2.从数据文件中取出数据绘制成图并保存

这样就可以容易理解上面的内容了。

最终我们可以获得使用性能测试数据绘制成的图片,较为完整地完成了一次性能测试

 

总结:

感谢每一个认真阅读我文章的人!!!

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

 

          视频文档获取方式:
这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方小卡片即可自行领取。

  • 18
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值