在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服务器为例来进行性能测试package mainimport ( "log" "net/http")func main() { http.HandleFunc("/echo", echo) log.Fatal(http.ListenAndServe(":8080", nil))}func echo(w http.ResponseWriter, r *http.Request) { q := r.URL.RawQuery w.Write([]byte(q))}wrk使用首先需要安装wrk# 下载源码git clone https://github.com/wg/wrkcd wrk# 编译make# 可执行文件移动到bin目录下cp ./wrk /usr/local/bin/wrk的使用并不复杂,参数也并不多,输入wrk命令就可以看到所有的参数了$ wrkUsage: wrk 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 -H, --header Add header to request --latency Print latency statistics --timeout Socket/request timeout -v, --version Print version details Numeric arguments may include a SI unit (1k, 1M, 1G) Time arguments may include a time unit (2s, 2m, 2h)参数说明:-c:并发数-d:测试的持续时间,默认为10s-t:线程数。(不要太多,为核数的2到4倍即可,太多反而会因为切换过于频繁而降低效率)-T:请求超时时间-H:指定请求的http header。--latency:打印响应时间分布-s:指定lua脚本启动echo服务程序,执行下面的命令来进行性能测试 wrk -t8 -c10000 -d20s -T20s --latency http://localhost:8080/echo?helloRunning 20s test @ http://localhost:8080/echo?hello 8 threads and 10000 connections Thread Stats Avg Stdev Max +/- Stdev Latency 54.00ms 36.72ms 530.63ms 76.74% Req/Sec 23.94k 4.89k 39.35k 67.50% Latency Distribution 50% 50.78ms 75% 62.96ms 90% 90.13ms 99% 198.25ms 3789262 requests in 20.09s, 437.26MB readRequests/sec: 188579.15Transfer/sec: 21.76MB用8个线程模拟10000个连接,持续20s进行测试。对于测试的结果,我们需要了解其含义。Thread Stats是线程统计,包括Latency和Req/Sec两部分。Latency:响应时间。有平均值,标准差,*大值,正负偏差在一个标准差范围内的占比。Req/Sec:每个线程每秒完成的请求数,同样有上面的四个值。Latency Distribution响应时间分布50%:50%的请求响应时间不超过50.78ms75%:75%的请求响应时间不超过62.96ms90%:90%的请求响应时间不超过90.13ms99%:99%的请求响应时间不超过198.25ms789262 requests in 20.09s, 437.26MB read:表示在20.09s内完成的总请求数为3789262,数据读取量为437.26MBRequests/sec:QPSTransfer/sec:平均每秒读取的数据量(吞吐量)如果我们将模拟的并发数调大一些,可能还会看到一组数据Socket errors: connect 21774, read 0, write 0, timeout 0:错误统计。包括连接失败请求个数,读失败请求个数,写失败请求个数,超时请求个数。数据可视化了解了wrk工具的使用,我们就可以不断调整并发数,然后执行wrk测试命令,将测试的结果使用awk提取出我们想要的指标,比如前文提到的并发数,QPS、TTLB等,然后输出到数据文件当中。使用gnuplot来从数据文件中获取数据并绘制成图片。首先,我们安装gnuplot工具$ sudo yum -y install gnuplot然后我们编写脚本来完成性能测试的数据收集以及图片的绘制。先完成整体的框架# wrk性能测试所用参数duration="20s"concurrent="200 500 1000 3000 5000 10000 15000 20000 25000 50000"threads=$((2 * `grep -c processor /proc/cpuinfo`))cmd="wrk -t${threads} -d${duration} -T30s --latency"wrkdir="./wrk"mkdir -p ${wrkdir}# 生成的文件名qpsttlb="echo_qps_ttlb.png"successrate="echo_successrate.png"datfile="echo.dat"# 性能测试流程for c in ${concurrent}do wrkcmd="${cmd} -c ${c} $1" echo "Running wrk command: ${wrkcmd}" result=`eval ${wrkcmd}` # 执行性能测试命令并获取结果 convert_plot_data "${result}" # 从结果中提取数据并保存为数据文件doneplot &> /dev/null #根据数据文件绘制出图片剩下就是两个函数了,首先是负责生成数据文件的convert_plot_data函数function convert_plot_data(){ # 传入wrk性能测试的执行结果,提取出需要的信息,写入文件当中 echo "$1" | awk -v datfile="${wrkdir}/${datfile}" " { if ($0 ~ "Running") { common_time=$2 }if ($0 ~ "connections") { connections=$4 common_threads=$1}if ($0 ~ "Latency ") { avg_latency=convertLatency($2)}if ($0 ~ "50%") { p50=convertLatency($2)}if ($0 ~ "75%") { p75=convertLatency($2)}if ($0 ~ "90%") { p90=convertLatency($2)}if ($0 ~ "99%") { p99=convertLatency($2)}if ($0 ~ "Requests/sec") { qps=$2}if ($0 ~ "requests in") { allrequest=$1}if ($0 ~ "Socket errors") { err=$4+$6+$8+$10}}END {rate=sprintf("%.2f", (allrequest-err)*100/allrequest)print connections,qps,avg_latency,rate >> datfile}function convertLatency(s) { if (s ~ "us") { sub("us", "", s) return s/1000 }if (s ~ "ms") { sub("ms", "", s) return s}if (s ~ "s") { sub("s", "", s) return s * 1000}}"}可以看到在print connections,qps,avg_latency,rate >> datfile中将指标写入数据文件。另外一个就是负责绘图的plot函数了function plot() { gnuplot << EOFset terminal png enhanced #输出格式为png文件set ylabel "QPS"set xlabel "Concurrent"set y2label "Average Latency (ms)"set key top left vertical noreverse spacing 1.2 boxset tics out nomirrorset border 3 frontset style line 1 linecolor rgb "#00ff00" linewidth 2 linetype 3 pointtype 2set style line 2 linecolor rgb "#ff0000" linewidth 1 linetype 3 pointtype 2set style data linespointsset grid #显示网格set xtics nomirror rotate #by 90#只需要一个x轴set mxtics 5set mytics 5 #可以增加分刻度set ytics nomirrorset y2ticsset autoscale yset autoscale y2set output "${wrkdir}/${qpsttlb}" #指定数据文件名称set title "QPS & TTLB\nRunning: ${duration}\nThreads: ${threads}"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)"unset y2ticsunset y2labelset ylabel "Success Rate"set ytics nomirrorset yrange[0:100]set output "${wrkdir}/${successrate}" #指定数据文件名称set title "Success Rate\nRunning: ${duration}\nThreads: ${threads}"plot "${wrkdir}/${datfile}" using 4:xticlabels(1) w lp pt 7 ps 1 lc rgbcolor "#F62817" t "Success Rate"EOF}有关gnuplot的使用这里就不过多介绍了,后续可能会专门开启一章进行学习,上面的内容虽然看着复杂,但是总体上就是两个部分:1.设置图片坐标轴的基本信息,以及样式2.从数据文件中取出数据绘制成图并保存这样就可以容易理解上面的内容了。最终我们可以获得使用性能测试数据绘制成的图片,较为完整地完成了一次性能测试END链接:https://www.cnblogs.com/smarticen/p/17077958本文经授权转载,转载文章所包含的文字来源于作者。如因内容或版权等问题,请联系进行删除点击下方“阅读原文”,寻找职业新风向~