最近在做服务器压测,想到可以通过 shell 脚本调用压测工具 ab 来进行多次测试。大致的想法是:
1. 通过 shell 脚本循环调用 ab 压测工具得到多次压测日志,并分类保存;
2.通过 shell 脚本循环调用 awk 工具将每个日志中的 90% 时间提取出来。
ab 工具
ab是apache自带的一个很好用的压力测试工具,当安装完apache的时候,就可以在bin下面找到ab。一个简单的 demo 如下:
ab -c 10 -n 100 -H "Authorization:Bearer nAuhWwS6xea7BcyCfVy5VoKF7MsAHDTtX7ABzN" http://domain/path
其中 -c 代表并发数,-n 代表请求数,-H 要发送的 Header。返回结果示例及各参数意义如下:
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 101.132.123.35 (be patient).....done
Server Software: Apache/2.4.18 # 服务器类型及其版本
Server Hostname: <Hostname> # 请求的主机名
Server Port: 84 # 端口号
Document Path: /v1/door/helps # 请求的路径
Document Length: 1143 bytes # 返回数据的大小
Concurrency Level: 10 # 并发规模
Time taken for tests: 0.934 seconds # 总请求时间
Complete requests: 100 # 完成的请求数
Failed requests: 0 # 失败的请求数
Total transferred: 131900 bytes # 总共传输的字节数
HTML transferred: 114300 bytes # 总 html 字节数
Requests per second: 107.04 [#/sec] (mean) # 吞吐量
Time per request: 93.427 [ms] (mean) # 用户平均等待时间
Time per request: 9.343 [ms] (mean, across all concurrent requests) # 服务器平均处理时间,即吞吐量倒数
Transfer rate: 137.87 [Kbytes/sec] received # 每秒获取的数据长度
Connection Times (ms)
min mean[+/-sd] median max
Connect: 7 9 1.2 9 13
Processing: 57 83 9.0 83 119
Waiting: 57 83 9.0 83 119
Total: 67 93 9.4 92 128
Percentage of the requests served within a certain time (ms)
50% 92
66% 95
75% 96
80% 99
90% 105 # 90%的请求在105ms内
95% 112
98% 119
99% 128
100% 128 (longest request)
shell 脚本多次测试
一个可多次进行压测的 demo 如下:
#!/bin/bash
urlIndex="http://Hostname/v1/door/helps"
Header="Authorization:Bearer nAuhTiWwS6xea7BcyCfVy5VoKF7MsAHDTtX7ABzN" # Header
declare -A concurrent
concurrent=(['c']=0 ['n']=100)
for i in {0..9};
do
let concurrent['c']+=10; # shell数值运算
dirName=tests/Getdb/c${concurrent['c']}n${concurrent['n']};
mkdir -p $dirName;
for j in {0..9};
do
outFile=${dirName}/"time"$j;
ab -c ${concurrent['c']} -n ${concurrent['n']} -H "${Header}" -e ${outFile} ${urlIndex};
done
done
要注意的是 shell 进行数值运算时不能对数字直接操作,需要使用 let 命令或者 [] 和 (()) 操作符。然后在 mkdir 的时候,最好带上 -p 参数,免得报错。 然后 -H 参数后面带字符串,需要用双引号包起来。
shell 脚本后处理输出日志
得到的日志目录如下图片所示
一个个查看日志文件中 90% 用时会显得比较麻烦,于是想到可以用 shell 脚本调用 awk 工具, demo 如下:
#!/bin/bash
declare -A concurrent
concurrent=(['c']=0 ['n']=100)
fileName="file.txt" # 输出文件名
for i in {0..9};
do
let concurrent['c']+=10;
dirName=tests/Get/c${concurrent['c']}n${concurrent['n']} # 取日志文件
echo ${dirName} >> $fileName # 输出测试条件,一行
for j in {0..9};
do
dataFile=${dirName}/"time"$j;
awk '/^90/{print}' ${dataFile} >> $fileName # 将 awk 输出的信息重定向到 file.txt 中
done
done
awk 的一般使用方法如下:
awk 'RegexPattern{command}' srcFile
' ' 内表示正则表达式+命令,如以下命令找出文件 time0 中以 "9”开头的行,并且输出到 file.txt 文件中。
awk '/^90/{print}' time0 >> file.txt