apache bench是乙個簡單易用的壓力測試工具,在這裡我不想多講。今天主要說的是寫乙個py指令碼來自動化測試過程,以及中間遇到的一些奇葩問題。
最終得到了乙個包含該框架所有測試資訊的json檔案,之所以採用json這種資料格式,是為了方便下一步處理。python
#!/usr/bin/env python
# encoding: utf-8
import sys
import subprocess as sub
import json
import re
import time
store=open(sys.argv[1],'w')
if len(sys.argv)>2:
total=sys.agrv[2]
else:
total=10000
if len(sys.argv)>3:
hostpath=sys.argv[3]
else:
hostpath=''
#url=['index','str','json','read','write','chain']
#cocurrency=[8,16,32,64,128,256]
url=['str','json','chain'];cocurrency=[16]
result=dict.fromkeys(url,{})
def parseab(src,dst):
src=src.split('\n')
pattern=re.compile(r'\d+\.\d')
for i in range(15,len(src)-10):
if(src[i].count(':')==0):
continue
tmp=src[i].split(':')
key=tmp[0]
data=pattern.findall(tmp[1])
if not data:
continue
elif(len(data)>1):
dst[key]=
for j in data:
dst[key]=dst[key]+[float(j)]
else:
dst[key]=float(data[0])
dst['percentage']={}
for i in range(len(src)-10,len(src)):
tmp=pattern.findall(src[i])
if(len(tmp)!=2):
continue
dst['percentage'][int(tmp[0])]=int(tmp[1])
return dst
for item in url:
for c in cocurrency:
child=sub.check_output('ab -k -n '+str(total)+' -c '+str(c)+' '+hostpath+item,shell=true,close_fds=true)
#child=sub.popen('ab -k -n '+str(total)+' -c '+str(c)+' '+hostpath+item,shell=true,close_fds=true,stdout=sub.pipe)
result[item][c]={}
parseab(child,result[item][c])
time.sleep(5)
store.write(json.dumps(result));
store.close()
最終暴露出乙個api介面python
#!/usr/bin/env python
# encoding: utf-8
import sys
import json
basepath=''
frame=['express']
data={}
for f in frame:
data[f]=json.loads(open(basepath+f+'.json','r').read())
url=data[frame[0]].keys()
cocurrency=data[frame[0]][url[0]].keys()
keylist=data[frame[0]][url[0]][cocurrency[0]].keys()
print 'you can get these key: '+str(keylist)
compare=dict.fromkeys(frame,dict.fromkeys(url,{}))
for f in frame:
for u in url:
for k in keylist:
datatype=type(data[f][u][cocurrency[0]][k])
if datatype==int or datatype==float:
tmp=
for c in cocurrency:
tmp=tmp+[datatype(data[f][u][c][k])]
compare[f][u][k]=tmp
elif datatype==dict:
percent=data[f][u][cocurrency[0]][k].keys()
tmp=dict.fromkeys(percent,)
for p in percent:
for c in cocurrency:
tmp[p]=tmp[p]+[data[f][u][c][k][p]]
compare[f][u][k]=tmp
elif datatype==list:
sta=['min','mean','sd','median','max']
tmp=dict.fromkeys(sta,)
for i in range(len(sta)):
for c in cocurrency:
s=sta[i]
tmp[s]=tmp[s]+[data[f][u][c][k][i]]
compare[f][u][k]=tmp
def get(f,u,k,index=none):
if k=='percentage':
if not index:
return compare[f][u][k]['95']
else:
return compare[f][u][k][str(index)]
elif type(compare[f][u][k])==dict:
if not index:
return compare[f][u][k]['mean']
else:
return compare[f][u][k][index]
else:
return compare[f][u][k]
在測試過程中(開始的指令碼不是這個樣子的,有略微的改變)到16000+請求的時候會卡主,並最終丟擲socket timeout的錯誤,錯誤碼60.為什麼會這樣子呢?python
import handle
handle.get('express','json','time per request')
//return an array for all cocurrency you choose
是由於系統資源的限制,socket在unix系統下也是利用檔案描述符的,socket的數量是有限制的,對於本人的mac是16387,據說對於linux系統是32000+,好,找到了問題所在,看來是子程序退出時沒有關閉socket。在python的bug報告裡提到了這個問題,在subprocess的呼叫中加一句close_fds=true可以在子程序執行之前關閉除了0,1,2的所有檔案描述符,自然就關閉了上次操作的所有sockets。
不過,這樣依舊不行。。。為什麼呢?因為不要忘了伺服器是localhost,關閉這些檔案描述符只是客戶端的socket.close(),意味著檔案描述符可以被再次分配,但服務端依然保有socket,它的資源沒有被釋放,限制依舊存在。想要立即釋放,我們應該用socket.shutdown(),不過這樣恐怕需要改寫subprocess,顯然蛋疼。
然後我就發現了我的測試語句
對,木有用-k,keep-alive選項允許socket被復用,不只是用於乙個http請求。同時我還在迴圈末尾加了一句sleep以等待資源被釋放。剩下的就只能聽天由命了。sh
ab -c 8 -n 10000 json
還有乙個非常常見的錯誤。
寫成這樣也會報錯哦!sh
ab -c 8 -n 10000 http://localhost:3000/json
最後向大家提乙個問題,為什麼用jmeter做壓力測試的時候,吞吐量會一開始很高,然後一直在下降?
使用apacheBench做壓力測試
乙個簡單的例子 在這個例子的一開始,我執行了這樣乙個命令ab n 10 c 10這個命令的意思是啟動 ab 向 www.google.com 傳送10個請求 n 10 並每次傳送10個請求 c 10 也就是說一次都發過去了。跟著下面的是 ab 輸出的測試報告,紅色部分是我新增的注釋。整個測試持續的時...
apache bench做web壓力測試詳解
apache bench 的介紹 戳這裡 apache bench 的官網 戳這裡 使用步驟 2 cmd下安裝相關服務 httpd k install 3 開始 執行 services.msc 確定 在windows服務列表找到apache類似的 說明服務安裝成功,右鍵選擇啟動服務。4 注意 修改埠...
apache bench壓測工具
效能指標維度 吞吐率 每秒事務處理數量,對應的是web的乙個請求介面完成一起請求響應的時間 計算公式 總請求數 處理完成這些請求數所花費的時間 併發請求數 每秒伺服器接收的請求數量 併發使用者數 每秒伺服器接收到的連線數量,乙個連線可以傳送多個請求數量 安裝 ubuntu系統下執行 apt inst...