摘要:為什么呢因?yàn)椴灰朔?wù)器是,關(guān)閉這些文件描述符只是客戶端的,意味著文件描述符可以被再次分配,但服務(wù)端依然保有,它的資源沒有被釋放,限制依舊存在。
Apache Bench是一個(gè)簡單易用的壓力測試工具,在這里我不想多講。今天主要說的是寫一個(gè)py腳本來自動(dòng)化測試過程,以及中間遇到的一些奇葩問題。
測試腳本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="http://127.0.0.1:3000/" #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(" ") pattern=re.compile(r"d+.{0,1}d{0,10}") 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()
最終得到了一個(gè)包含該框架所有測試信息的json文件,之所以采用json這種數(shù)據(jù)格式,是為了方便下一步處理。
解析腳本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]
最終暴露出一個(gè)API接口
pythonimport handle handle.get("express","json","Time per request") //return an array for all cocurrency you choose遇到的問題
在測試過程中(開始的腳本不是這個(gè)樣子的,有略微的改變)到16000+請求的時(shí)候會(huì)卡主,并最終拋出socket timeout的錯(cuò)誤,錯(cuò)誤碼60.為什么會(huì)這樣子呢?
是由于系統(tǒng)資源的限制,socket在unix系統(tǒng)下也是利用文件描述符的,socket的數(shù)量是有限制的,對于本人的MAC是16387,據(jù)說對于linux系統(tǒng)是32000+,好,找到了問題所在,看來是子進(jìn)程退出時(shí)沒有關(guān)閉socket。在python的bug報(bào)告里提到了這個(gè)問題,在subprocess的調(diào)用中加一句close_fds=True可以在子進(jìn)程執(zhí)行之前關(guān)閉除了0,1,2的所有文件描述符,自然就關(guān)閉了上次操作的所有sockets。
不過,這樣依舊不行。。。為什么呢?因?yàn)椴灰朔?wù)器是localhost,關(guān)閉這些文件描述符只是客戶端的socket.close(),意味著文件描述符可以被再次分配,但服務(wù)端依然保有socket,它的資源沒有被釋放,限制依舊存在。想要立即釋放,我們應(yīng)該用socket.shutdown(),不過這樣恐怕需要改寫subprocess,顯然蛋疼。
然后我就發(fā)現(xiàn)了我的測試語句
shab -c 8 -n 10000 http://127.0.0.1:3000/json
對,木有用-k,keep-alive選項(xiàng)允許socket被復(fù)用,不只是用于一個(gè)http請求。同時(shí)我還在循環(huán)末尾加了一句sleep以等待資源被釋放。剩下的就只能聽天由命了。
還有一個(gè)非常常見的錯(cuò)誤。
shab -c 8 -n 10000 http://localhost:3000/json
寫成這樣也會(huì)報(bào)錯(cuò)哦!
結(jié)語最后向大家提一個(gè)問題,為什么用Jmeter做壓力測試的時(shí)候,吞吐量會(huì)一開始很高,然后一直在下降?
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/37488.html
Apache Bench apt-get install apache2-utils yum install httpd-tools 使用方法: ab -n 100 -c 10 -l http://www.your_site.com/ -n number 總的請求數(shù) -c concurrency 并發(fā)數(shù) -l 表示當(dāng)某個(gè)請求的回復(fù)長度不與第一個(gè)請求的回復(fù)長度一致時(shí),不把它作為失敗的請求 -p 發(fā)送...
摘要:測試對于互聯(lián)網(wǎng)應(yīng)用軟件開發(fā)來說非常重要,它對軟件可靠性保證具有重要意義,通過測試能夠盡可能發(fā)現(xiàn)并改正軟件中的錯(cuò)誤,提高軟件質(zhì)量。這里我們主要講解語言如何實(shí)現(xiàn)單元測試和性能測試。單元測試創(chuàng)建目錄,在目錄下創(chuàng)建兩個(gè)文件,為單元測試文件。 測試對于互聯(lián)網(wǎng)應(yīng)用軟件開發(fā)來說非常重要,它對軟件可靠性保證具有重要意義,通過測試能夠盡可能發(fā)現(xiàn)并改正軟件中的錯(cuò)誤,提高軟件質(zhì)量。 這里我們主要講解Go語言...
摘要:兩個(gè)事件驅(qū)動(dòng)模型服務(wù)器平均每秒處理的請求數(shù)為服務(wù)器的一倍,而內(nèi)存降低了一半。事件驅(qū)動(dòng)模型的出現(xiàn),是為了解決傳統(tǒng)服務(wù)器與網(wǎng)絡(luò)工作負(fù)載的需求的不匹配,實(shí)現(xiàn)高度可伸縮服務(wù)器,并降低內(nèi)存開銷。 from http://oyanglul.us 本文基本上這為兩篇文章的翻譯和整合 -...
摘要:用例運(yùn)行爬蟲命令基本語法是否需要項(xiàng)目存在當(dāng)然是不需要咯貌似這個(gè)命令是不依托一個(gè)項(xiàng)目而直接運(yùn)行一個(gè)爬蟲的命令。用例我終于寫完了,喜歡的就收藏推薦一下吧,這樣我就會(huì)更有動(dòng)力寫新的教程了,哇哈哈 0. 基本環(huán)境說明 本文截圖及運(yùn)行環(huán)境均在Win8上實(shí)現(xiàn)(是的,我放假回家了,家里的機(jī)器是win8的沒有辦法),但基本步驟與win 7環(huán)境基本相同。(應(yīng)該把~)ps:我后來換了臺(tái)win7的電腦,所...
閱讀 3303·2021-11-24 09:39
閱讀 2809·2021-10-12 10:20
閱讀 1917·2019-08-30 15:53
閱讀 3082·2019-08-30 14:14
閱讀 2610·2019-08-29 15:36
閱讀 1128·2019-08-29 14:11
閱讀 1960·2019-08-26 13:51
閱讀 3414·2019-08-26 13:23