使用ab工具对服务器进行API压力测试
1 系统吞吐量的简单介绍
一个系统的吞度量(承压能力)与request对cpu的消耗、外部接口、io等等紧密关联。
单个reqeust 对cpu消耗越高,外部系统接口、io影响速度越慢,系统吞吐能力越低,反之越高。
系统吞吐量几个重要参数:tps、并发数、响应时间
- tps:每秒钟处理的事务数量
- 并发量: 系统同时处理请求数(事务数)
- 响应时间: 一般取平均响应时间
tps= 并发量/平均响应时间
这里因为说的事务如果是单一接口请求,我们也可以认为tps即为qps。
下面举例说明:
比如3000个用户(并发量)同时访问待测试接口,在用户端统计,3000个用户平均得到响应的时间为1188.538ms。所以tps=3000/1.188538s= 2524.11 q/s。
我们就可以这样描述本次测试,在3000个并发量的情况下,tps为2524.11,平均响应事件为1188.538ms
tps:在实际测试中表现为:
一个系统吞吐量通常由tps、并发数两个因素决定,每套系统这两个值都有一个相对极限值,在应用场景访问压力下,只要某一项达 到系统最高值,系统的吞吐量就上不去了,如果压力继续增大,系统的吞吐量反而会下降,原因是系统超负荷工作,上下文切换、内存等等其它消耗导致系统性能下降。
实际表现为tps即先上升后下降,我们需要找到性能拐点。并得到限制瓶颈。
2 测试方法
参考文献(详细输出说明):
2.1 客户端测试工具
我们采用apachebench 工具进行测试。
ubuntu安装ab:
sudo apt-get install apache2-utils
linux默认登录端口只能打开1024个文件,因为在linux一切皆文件,所以ab并发数受到整个打开文件数的限制,需要使用ulimit -n 10000(打开文件数)进行修改后才能支持较大的并发。本人测试修改到15000。
2.1.1 get方法
ab -n 100 -c 100 https://www.baidu.com/index.html
-n:请求 总数
-c:并发用户数.
-url:待测api。
当测试发起请求数量较少,完成较快,无中间过程显示。在请求数量很多时会分行显示当前完成数量。
2.1.2 post方法
ab -n 10 -c 1 -t 'application/x-www-form-urlencoded' -h "authorization:bearer 2393d8db9b9d7f4b9d1570cc8776bca69b421b62" -p ./post http://172.28.28.17:3017/oauth2/token
- -h:可以设置响应header
- -t: post http header类型 默认为text/plain
- -p:post body内容, ab要求写在文件中,-p后跟文件目录,文件内容如name=hello&password=1234
2.1.3 测试结果解读
来份ab的测试输出:
ab -n 10 -c 2 上图结果为总请求10 并发为2的结果
我们主要关注的输出信息为:
- concurrency level: 10 //并发级别,也就是并发数,请求中-c参数指定的数量
- time taken for tests: 1.093 seconds //本次测试总共花费的时间
- complete requests: 100 //本次测试总共发起的请求数量
- failed requests: 0 //失败的请求数量。因网络原因或服务器性能原因,发起的请求并不一定全部成功,通过该数值和complete requests相除可以计算请求的失败率,作为测试结果的重要参考。
- total transferred: 103314 bytes //总共传输的数据量,指的是ab从被测服务器接收到的总数据量,包括index.html的文本内容和请求头信息。
- requests per second: 91.50 [#/sec] (mean) //平均(mean)每秒完成的请求数:qps,这是一个平均值,等于complete requests/time taken for tests=100/1.093=91.50
- time per request: 109.287 [ms] (mean) //从用户角度看,完成一个请求所需要的时间(因用户数量不止一个,服务器完成10个请求,平均每个用户才接收到一个完整的返回,所以该值是下一项数值的10倍。)
- time per request: 10.929 [ms] (mean, across all concurrent requests)// 服务器完成一个请求的时间。
- transfer rate: 92.32 [kbytes/sec] received //网络传输速度。对于大文件的请求测试,这个值很容易成为系统瓶颈所在。要确定该值是不是瓶颈,需要了解客户端和被测服务器之间的网络情况,包括网络带宽和网卡速度等信息。
其中我们最为关注的为requests per second: 即tps。我们将它最为服务器性能最为重要的指标。
2.2服务器端检测方法
可以通过 iftop命令和nethogs -d 对服务器网络情况进行检测。
可以通过iptables命令监控服务器端口流量。
可以通过 top | grep “node” 对内存和cpu进行判断。
对云上测试 可以使用云主机后台,但后台参数是分钟级后的平均值。
感觉好像这样测优点蠢
3 实际测试
使用apachebench 可以使用编写shell脚本进行多次测试。可以将待测api 放入api数组并修改循环数量,实现一次测试多个api并生成关键参数xls文件。现在看来还是原来太天真才会有这种想法。
3.1 shell脚本
使用说明:a 是请求总数 ,b是并发用户数一一对应,即a[0]对应b[0],传入参数第一个是待测api服务器地址,第二个是api所需参数。api设置在api数组中。添加多个api 或同意api多组测试请修改循环计数。
echo "you maybe use this sh like:"$0" serverip userparam" a=(1000 2000 4000 6000 7000)#待测请求总数 b=(50 100 200 300 400)#并发用户数 runtime=$(date +%y%m%d%h%m%s) if [ -z "$1"] then serverip="http://127.0.0.1" else serverip=$1 fi if [ -z "$2"] then param="deviceid=xxx&bindingplatform=xxx&bindingid=xxx" else param=$2 fi filename=${runtime}"-test.log" touch filename #api=('xxx'${param} 'xxx'${param} '/users/account') api=('xxx'${param}) echo "********webserver test info*************" echo "testtime :"$(date) echo "logname :"${filename} echo "serverip :"${serverip} echo "userparam:"${param} echo "********webserver test info*************" #echo ${filename} for j in {0..0}#待测api个数 即api数组数 do echo "api test:"${serverip}${api[j]} for i in {0..4}#待测api测试次数 5次也就是对应a b数组有个五个值 do ab -r -k -n ${a[i]} -c ${b[i]} -c ${param} ${serverip}${api[j]} | grep -e"document path:" -e "complete requests:" -e "concurrency level:" -e"failed requests:" -e"time taken for tests:" -e "requests per second:" -e "time per request" -e"total transferred: " >> ${filename} done done sed -i 's/^.\{24\}//g' ${filename}# 按照时间生成txt文件 并按上面的参数进行提取。 export ld_library_path= ./change ${filename} ${runtime}"report.xls"#chang 函数功能是将txt中关键数据变成xls文件。 rm ${filename}
3.2 c++提取程序:使用了libxl.h
#include <iostream> #include <fstream> #include <string> #include "libxl.h" using namespace std; using namespace libxl; int main(int agrc, char *argc[]) { //cout << "helloworld" << endl; fstream f; ifstream ifile(argc[1]); string temp; int i = 0, j=1, k = 0; book* book = xlcreatebook();//创建一个二进制格式的xls(execl97-03)的实例,在使用前必须先调用这个函数创建操作excel的对象 //book->setkey(......);//如果购买了该库,则设置相应的key,若没有购买,则不用这行 if (book)//是否创建实例成功 { sheet* sheet = book->addsheet("sheet1");//添加一个工作表 for(i=0;i<30;i++) { for(j=0;j<10;j++){ sheet->setcol(i, j, 20);//设置列宽,格式等 } } i=0; j=1; if (sheet) { sheet->writestr(j, 0, "api"); sheet->writestr(j, 1, "concurrency level"); sheet->writestr(j, 2, "time taken for tests"); sheet->writestr(j, 3, "complete requests"); sheet->writestr(j, 4, "failed requests"); sheet->writestr(j, 5, "total transferred"); sheet->writestr(j, 6, "requests per second"); sheet->writestr(j, 7, "time per reques(user)"); sheet->writestr(j, 8, "time per reques(server)"); j++; while (getline(ifile, temp)) { if (temp[0] == '/'){ f << temp << " "; sheet->writestr(j, i, temp.c_str()); } else if (temp.find('[') != string::npos){ f << temp.substr(0, temp.find('[') - 1) << " "; sheet->writestr(j, i, temp.substr(0, temp.find('[') - 1).c_str()); } else if (temp.find('b') != string::npos){ f << temp.substr(0, temp.find('b') - 1) << " "; sheet->writestr(j, i, temp.substr(0, temp.find('b') - 1).c_str()); } else if (temp.find('s') != string::npos){ sheet->writestr(j, i, temp.substr(0, temp.find('s') - 1).c_str()); f << temp.substr(0, temp.find('s') - 1) << " "; } else{ sheet->writestr(j, i, temp.c_str()); f << temp << " "; } i++; if (i == 9){ f << " " << endl; i = 0; j++; } } ifile.close(); } if (book->save(argc[2]))//保存到example.xls { //..... } else { std::cout << book->errormessage() << std::endl; } book->release();} return 0; }
4 测试中遇到一些问题
在用云主机时要注意一下云主机带宽的问题,小水管很可能成为瓶颈。
ab软件中total transferred 与端口流量有差距。端口流量大于total transferred,猜测是有封包的因素。所以不能把total transferred作为服务器消耗的流量来处理,用于计算云上某些按流量消耗的服务。
git:https://github.com/collapsarli/server_apachebench_shell.git
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
Linux中安装使用http_load对服务器进行压力测试的教程
-
使用Apache ab工具对Apache服务器进行简单的压力测试
-
使用AB进行压力测试
-
使用JMeter对Tomcat进行压力测试与Tomcat性能调优
-
在Linux系统的服务器上使用Memtester进行内存压力测试
-
Linux(服务器编程):50---Web压力测试工具(Apache Bench,ab)
-
使用Apache的ab工具进行压力测试
-
使用 WRK 压力测试工具对 ASP.NET Core 的接口进行压力测试
-
使用ab工具对服务器进行API压力测试
-
使用Jmeter对Mysql进行压力测试无法执行多条sql语句问题_MySQL