您好,登錄后才能下訂單哦!
本篇文章為大家展示了如何使用ab工具對(duì)服務(wù)器進(jìn)行API壓力測(cè)試,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。
一個(gè)系統(tǒng)的吞度量(承壓能力)與request對(duì)CPU的消耗、外部接口、IO等等緊密關(guān)聯(lián)。
單個(gè)reqeust 對(duì)CPU消耗越高,外部系統(tǒng)接口、IO影響速度越慢,系統(tǒng)吞吐能力越低,反之越高。
系統(tǒng)吞吐量幾個(gè)重要參數(shù):TPS、并發(fā)數(shù)、響應(yīng)時(shí)間
TPS:每秒鐘處理的事務(wù)數(shù)量
并發(fā)量: 系統(tǒng)同時(shí)處理請(qǐng)求數(shù)(事務(wù)數(shù))
響應(yīng)時(shí)間: 一般取平均響應(yīng)時(shí)間
TPS= 并發(fā)量/平均響應(yīng)時(shí)間
這里因?yàn)檎f(shuō)的事務(wù)如果是單一接口請(qǐng)求,我們也可以認(rèn)為T(mén)PS即為QPS。
下面舉例說(shuō)明:
比如3000個(gè)用戶(并發(fā)量)同時(shí)訪問(wèn)待測(cè)試接口,在用戶端統(tǒng)計(jì),3000個(gè)用戶平均得到響應(yīng)的時(shí)間為1188.538ms。所以TPS=3000/1.188538s= 2524.11 q/s。
我們就可以這樣描述本次測(cè)試,在3000個(gè)并發(fā)量的情況下,TPS為2524.11,平均響應(yīng)事件為1188.538ms
Tps:在實(shí)際測(cè)試中表現(xiàn)為:
一個(gè)系統(tǒng)吞吐量通常由TPS、并發(fā)數(shù)兩個(gè)因素決定,每套系統(tǒng)這兩個(gè)值都有一個(gè)相對(duì)極限值,在應(yīng)用場(chǎng)景訪問(wèn)壓力下,只要某一項(xiàng)達(dá) 到系統(tǒng)最高值,系統(tǒng)的吞吐量就上不去了,如果壓力繼續(xù)增大,系統(tǒng)的吞吐量反而會(huì)下降,原因是系統(tǒng)超負(fù)荷工作,上下文切換、內(nèi)存等等其它消耗導(dǎo)致系統(tǒng)性能下降。
實(shí)際表現(xiàn)為tps即先上升后下降,我們需要找到性能拐點(diǎn)。并得到限制瓶頸。
參考文獻(xiàn)(詳細(xì)輸出說(shuō)明):
http://kemok4.com/article/231492.htm
我們采用apacheBench 工具進(jìn)行測(cè)試。
ubuntu安裝ab:
sudo apt-get install apache2-utils
linux默認(rèn)登錄端口只能打開(kāi)1024個(gè)文件,因?yàn)樵趌inux一切皆文件,所以ab并發(fā)數(shù)受到整個(gè)打開(kāi)文件數(shù)的限制,需要使用ulimit -n 10000(打開(kāi)文件數(shù))進(jìn)行修改后才能支持較大的并發(fā)。本人測(cè)試修改到15000。
ab -n 100 -c 100 https://www.baidu.com/index.html
-n:請(qǐng)求 總數(shù)
-c:并發(fā)用戶數(shù).
-url:待測(cè)api。
當(dāng)測(cè)試發(fā)起請(qǐng)求數(shù)量較少,完成較快,無(wú)中間過(guò)程顯示。在請(qǐng)求數(shù)量很多時(shí)會(huì)分行顯示當(dāng)前完成數(shù)量。
ab -n 10 -c 1 -T 'application/x-www-form-urlencoded' -H "Authorization:Bearer 2393d8db9b9d7f4b9d1570cc8776bca69b421b62" -p ./post http://172.28.28.17:3017/oauth3/token
-H:可以設(shè)置響應(yīng)header
-T: Post http header類(lèi)型 默認(rèn)為text/plain
-P:Post body內(nèi)容, ab要求寫(xiě)在文件中,-p后跟文件目錄,文件內(nèi)容如name=hello&password=1234
來(lái)份ab的測(cè)試輸出:
ab -n 10 -c 2 上圖結(jié)果為總請(qǐng)求10 并發(fā)為2的結(jié)果
我們主要關(guān)注的輸出信息為:
Concurrency Level: 10 //并發(fā)級(jí)別,也就是并發(fā)數(shù),請(qǐng)求中-c參數(shù)指定的數(shù)量
Time taken for tests: 1.093 seconds //本次測(cè)試總共花費(fèi)的時(shí)間
Complete requests: 100 //本次測(cè)試總共發(fā)起的請(qǐng)求數(shù)量
Failed requests: 0 //失敗的請(qǐng)求數(shù)量。因網(wǎng)絡(luò)原因或服務(wù)器性能原因,發(fā)起的請(qǐng)求并不一定全部成功,通過(guò)該數(shù)值和Complete requests相除可以計(jì)算請(qǐng)求的失敗率,作為測(cè)試結(jié)果的重要參考。
Total transferred: 103314 bytes //總共傳輸?shù)臄?shù)據(jù)量,指的是ab從被測(cè)服務(wù)器接收到的總數(shù)據(jù)量,包括index.html的文本內(nèi)容和請(qǐng)求頭信息。
Requests per second: 91.50 [#/sec] (mean) //平均(mean)每秒完成的請(qǐng)求數(shù):QPS,這是一個(gè)平均值,等于Complete requests/Time taken for tests=100/1.093=91.50
Time per request: 109.287 [ms] (mean) //從用戶角度看,完成一個(gè)請(qǐng)求所需要的時(shí)間(因用戶數(shù)量不止一個(gè),服務(wù)器完成10個(gè)請(qǐng)求,平均每個(gè)用戶才接收到一個(gè)完整的返回,所以該值是下一項(xiàng)數(shù)值的10倍。)
Time per request: 10.929 [ms] (mean, across all concurrent requests)// 服務(wù)器完成一個(gè)請(qǐng)求的時(shí)間。
Transfer rate: 92.32 [Kbytes/sec] received //網(wǎng)絡(luò)傳輸速度。對(duì)于大文件的請(qǐng)求測(cè)試,這個(gè)值很容易成為系統(tǒng)瓶頸所在。要確定該值是不是瓶頸,需要了解客戶端和被測(cè)服務(wù)器之間的網(wǎng)絡(luò)情況,包括網(wǎng)絡(luò)帶寬和網(wǎng)卡速度等信息。
其中我們最為關(guān)注的為Requests per second: 即tps。我們將它最為服務(wù)器性能最為重要的指標(biāo)。
可以通過(guò) iftop命令和nethogs -d 對(duì)服務(wù)器網(wǎng)絡(luò)情況進(jìn)行檢測(cè)。
可以通過(guò)iptables命令監(jiān)控服務(wù)器端口流量。
可以通過(guò) top | grep “node” 對(duì)內(nèi)存和cpu進(jìn)行判斷。
對(duì)云上測(cè)試 可以使用云主機(jī)后臺(tái),但后臺(tái)參數(shù)是分鐘級(jí)后的平均值。
感覺(jué)好像這樣測(cè)優(yōu)點(diǎn)蠢
使用apacheBench 可以使用編寫(xiě)shell腳本進(jìn)行多次測(cè)試。可以將待測(cè)api 放入api數(shù)組并修改循環(huán)數(shù)量,實(shí)現(xiàn)一次測(cè)試多個(gè)api并生成關(guān)鍵參數(shù)xls文件?,F(xiàn)在看來(lái)還是原來(lái)太天真才會(huì)有這種想法。
使用說(shuō)明:a 是請(qǐng)求總數(shù) ,b是并發(fā)用戶數(shù)一一對(duì)應(yīng),即a[0]對(duì)應(yīng)b[0],傳入?yún)?shù)第一個(gè)是待測(cè)api服務(wù)器地址,第二個(gè)是api所需參數(shù)。api設(shè)置在api數(shù)組中。添加多個(gè)api 或同意api多組測(cè)試請(qǐng)修改循環(huán)計(jì)數(shù)。
echo "you maybe use this sh like:"$0" serverIP userParam" a=(1000 2000 4000 6000 7000)#待測(cè)請(qǐng)求總數(shù) b=(50 100 200 300 400)#并發(fā)用戶數(shù) 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}#待測(cè)api個(gè)數(shù) 即api數(shù)組數(shù) do echo "API test:"${serverip}${api[j]} for i in {0..4}#待測(cè)api測(cè)試次數(shù) 5次也就是對(duì)應(yīng)a b數(shù)組有個(gè)五個(gè)值 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}# 按照時(shí)間生成txt文件 并按上面的參數(shù)進(jìn)行提取。 export LD_LIBRARY_PATH= ./change ${filename} ${runTime}"report.xls"#chang 函數(shù)功能是將txt中關(guān)鍵數(shù)據(jù)變成xls文件。 rm ${filename}
#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();//創(chuàng)建一個(gè)二進(jìn)制格式的XLS(Execl97-03)的實(shí)例,在使用前必須先調(diào)用這個(gè)函數(shù)創(chuàng)建操作excel的對(duì)象 //book->setKey(......);//如果購(gòu)買(mǎi)了該庫(kù),則設(shè)置相應(yīng)的key,若沒(méi)有購(gòu)買(mǎi),則不用這行 if (book)//是否創(chuàng)建實(shí)例成功 { Sheet* sheet = book->addSheet("Sheet1");//添加一個(gè)工作表 for(i=0;i<30;i++) { for(j=0;j<10;j++){ sheet->setCol(i, j, 20);//設(shè)置列寬,格式等 } } 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; }
在用云主機(jī)時(shí)要注意一下云主機(jī)帶寬的問(wèn)題,小水管很可能成為瓶頸。
ab軟件中Total transferred 與端口流量有差距。端口流量大于Total transferred,猜測(cè)是有封包的因素。所以不能把Total transferred作為服務(wù)器消耗的流量來(lái)處理,用于計(jì)算云上某些按流量消耗的服務(wù)。
上述內(nèi)容就是如何使用ab工具對(duì)服務(wù)器進(jìn)行API壓力測(cè)試,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。