Apache Bench做壓力測試

2021-06-28 02:09:32 字數 4512 閱讀 4079

apache bench是乙個簡單易用的壓力測試工具,在這裡我不想多講。今天主要說的是寫乙個py指令碼來自動化測試過程,以及中間遇到的一些奇葩問題。

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()

最終得到了乙個包含該框架所有測試資訊的json檔案,之所以採用json這種資料格式,是為了方便下一步處理。

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]

最終暴露出乙個api介面

pythonimport handle

handle.get('express','json','time per request')

//return an array for all cocurrency you choose

在測試過程中(開始的指令碼不是這個樣子的,有略微的改變)到16000+請求的時候會卡主,並最終丟擲socket timeout的錯誤,錯誤碼60.為什麼會這樣子呢?

是由於系統資源的限制,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,顯然蛋疼。

然後我就發現了我的測試語句

shab -c 8 -n 10000 json
對,木有用-k,keep-alive選項允許socket被復用,不只是用於乙個http請求。同時我還在迴圈末尾加了一句sleep以等待資源被釋放。剩下的就只能聽天由命了。

還有乙個非常常見的錯誤。

shab -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...