成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Apache Bench做壓力測試

entner / 2392人閱讀

摘要:為什么呢因為不要忘了服務器是,關閉這些文件描述符只是客戶端的,意味著文件描述符可以被再次分配,但服務端依然保有,它的資源沒有被釋放,限制依舊存在。


前言

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

最終得到了一個包含該框架所有測試信息的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.為什么會這樣子呢?

是由于系統(tǒng)資源的限制,socket在unix系統(tǒng)下也是利用文件描述符的,socket的數量是有限制的,對于本人的MAC是16387,據說對于linux系統(tǒng)是32000+,好,找到了問題所在,看來是子進程退出時沒有關閉socket。在python的bug報告里提到了這個問題,在subprocess的調用中加一句close_fds=True可以在子進程執(zhí)行之前關閉除了0,1,2的所有文件描述符,自然就關閉了上次操作的所有sockets。

不過,這樣依舊不行。。。為什么呢?因為不要忘了服務器是localhost,關閉這些文件描述符只是客戶端的socket.close(),意味著文件描述符可以被再次分配,但服務端依然保有socket,它的資源沒有被釋放,限制依舊存在。想要立即釋放,我們應該用socket.shutdown(),不過這樣恐怕需要改寫subprocess,顯然蛋疼。

然后我就發(fā)現了我的測試語句

shab -c 8 -n 10000 http://127.0.0.1:3000/json

對,木有用-k,keep-alive選項允許socket被復用,不只是用于一個http請求。同時我還在循環(huán)末尾加了一句sleep以等待資源被釋放。剩下的就只能聽天由命了。

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

shab -c 8 -n 10000 http://localhost:3000/json

寫成這樣也會報錯哦!

結語

最后向大家提一個問題,為什么用Jmeter做壓力測試的時候,吞吐量會一開始很高,然后一直在下降?

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/37488.html

相關文章

  • 服務器壓力測試Apache Bench和siege

    Apache Bench apt-get install apache2-utils yum install httpd-tools 使用方法: ab -n 100 -c 10 -l http://www.your_site.com/ -n number 總的請求數 -c concurrency 并發(fā)數 -l 表示當某個請求的回復長度不與第一個請求的回復長度一致時,不把它作為失敗的請求 -p 發(fā)送...

    CoorChice 評論0 收藏0
  • Go 單元測試和性能測試

    摘要:測試對于互聯(lián)網應用軟件開發(fā)來說非常重要,它對軟件可靠性保證具有重要意義,通過測試能夠盡可能發(fā)現并改正軟件中的錯誤,提高軟件質量。這里我們主要講解語言如何實現單元測試和性能測試。單元測試創(chuàng)建目錄,在目錄下創(chuàng)建兩個文件,為單元測試文件。 測試對于互聯(lián)網應用軟件開發(fā)來說非常重要,它對軟件可靠性保證具有重要意義,通過測試能夠盡可能發(fā)現并改正軟件中的錯誤,提高軟件質量。 這里我們主要講解Go語言...

    SimonMa 評論0 收藏0
  • [gist]為什么事件驅動服務器這么火

    摘要:兩個事件驅動模型服務器平均每秒處理的請求數為服務器的一倍,而內存降低了一半。事件驅動模型的出現,是為了解決傳統(tǒng)服務器與網絡工作負載的需求的不匹配,實現高度可伸縮服務器,并降低內存開銷。 from http://oyanglul.us 本文基本上這為兩篇文章的翻譯和整合 -...

    fsmStudy 評論0 收藏0
  • scrapy入門教程3:scrapy的shell命令

    摘要:用例運行爬蟲命令基本語法是否需要項目存在當然是不需要咯貌似這個命令是不依托一個項目而直接運行一個爬蟲的命令。用例我終于寫完了,喜歡的就收藏推薦一下吧,這樣我就會更有動力寫新的教程了,哇哈哈 0. 基本環(huán)境說明 本文截圖及運行環(huán)境均在Win8上實現(是的,我放假回家了,家里的機器是win8的沒有辦法),但基本步驟與win 7環(huán)境基本相同。(應該把~)ps:我后來換了臺win7的電腦,所...

    zhongmeizhi 評論0 收藏0

發(fā)表評論

0條評論

entner

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<