性能测试中P99的计算
性能中的測(cè)試指標(biāo)有很多,對(duì)于響應(yīng)時(shí)間,除了查看90%、95%、99%的響應(yīng)時(shí)間外,現(xiàn)在還有一個(gè)P99(可能比較小眾,所以相關(guān)資料較少),表示過(guò)去 10 秒內(nèi)最慢的 1% 請(qǐng)求的平均延遲。這個(gè)值的意義在于:如果這個(gè)值從測(cè)試開(kāi)始到測(cè)試結(jié)束變化都不大的話(huà),說(shuō)明程序比較穩(wěn)定,如果變化非常大,起起伏伏,說(shuō)明程序里面有些地方在某種情況下有些邏輯沒(méi)有處理好,導(dǎo)致問(wèn)題,當(dāng)然需要結(jié)合其他的內(nèi)存,CPU,IOPS以及當(dāng)前的請(qǐng)求數(shù),響應(yīng)數(shù)等等,這個(gè)在亞馬遜云服務(wù)器也有說(shuō)明。https://docs.aws.amazon.com/zh_cn/elasticbeanstalk/latest/dg/health-enhanced-metrics.html
那么怎么得到這個(gè)值呢?在使用jmeter性能測(cè)試中,發(fā)現(xiàn)插件和各種處理器都沒(méi)有提供這個(gè)值的直接獲取。那么我們就自己來(lái)編寫(xiě)腳本獲取了,思路如下:①通過(guò)jmeter腳本導(dǎo)出每個(gè)請(qǐng)求的響應(yīng)時(shí)間和結(jié)束時(shí)間;②通過(guò)Python腳本計(jì)算P99的值,并做出折線圖。具體步驟如下:
一、通過(guò)jmeter腳本導(dǎo)出每個(gè)請(qǐng)求的響應(yīng)時(shí)間和結(jié)束時(shí)間;
1、安裝插件:Flexible File Writer
2、編輯Flexible File Writer,獲取響應(yīng)時(shí)間和結(jié)束時(shí)間等值,保存在txt文檔里,用以后面處理
其中filename 是保存的文件路徑;write file header 是保存文件中的第一行說(shuō)明,用以標(biāo)識(shí)每列的信息,值中間用空格隔開(kāi);record each sample as 記錄的是每個(gè)樣本對(duì)應(yīng)的參數(shù)值,記錄時(shí),需要和下面的available sample fields保持一致(點(diǎn)擊即可復(fù)制),值中間用| |隔開(kāi)。
3、腳本運(yùn)行后,就會(huì)記錄對(duì)應(yīng)的值在剛保存的txt文檔里,例子如下:
Python讀取第二行的內(nèi)容是:b'426 1616068614679 2.get meetingroom inf 426 200
'
二、通過(guò)Python腳本計(jì)算P99的值,并做出折線圖。
具體思路如下:
1、讀取文本文件,獲取第一列和第二列的值,并把這些值保存在列表里。第一列的值是響應(yīng)時(shí)間,第二列的值是endtime;
2、定義一個(gè)函數(shù),用于計(jì)算99%之外的響應(yīng)時(shí)間的平均數(shù);
3、使用循環(huán)語(yǔ)句,計(jì)算所有過(guò)去10秒內(nèi)的響應(yīng)時(shí)間的開(kāi)始位置和結(jié)束位置,當(dāng)總的結(jié)束時(shí)間不超過(guò)10S時(shí),也需要考慮;然后每個(gè)位置調(diào)用步驟2中的函數(shù),得到P99列表;
4、計(jì)算出需要繪圖的X軸和Y軸列表。X軸用相對(duì)結(jié)束時(shí)間列表,Y軸用P99列表;使用matplotlib這個(gè)數(shù)學(xué)繪圖庫(kù)進(jìn)行繪圖。
5、完整代碼如下:
# -*- coding: utf-8 -*-
import logging
import matplotlib.pyplot as plt #Python數(shù)據(jù)可視化最流行的工具之一是 matplotlib,它是一個(gè)數(shù)學(xué)繪圖庫(kù)
import numpy as np
logging.basicConfig(level=logging.DEBUG, filename='logger.log',format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') # 設(shè)置日志級(jí)別
file=r'F:/99.practice/paixu/testresult.txt'
other_ave=99
#獲取文檔中第一列:響應(yīng)時(shí)間,輸入到列表里
restimelist=[] #響應(yīng)時(shí)間列表
endtimelist=[] #結(jié)束時(shí)間列表
otheravelist=[] #其他外響應(yīng)時(shí)間平均值列表
othertimelist=[] #其他結(jié)束時(shí)間值列表
findstring='\'
with open(file,'rb+') as f:
content=f.readlines() #readlines返回文件中行內(nèi)容列表
lines=len(content) #readlines返回文件中行內(nèi)容列表,列表長(zhǎng)度即為行數(shù)
#print(lines)
print(content[1]) #顯示第2行內(nèi)容,例如:b'426 1616068614679 2.get meetingroom inf 426 200 '
for i in range(lines):
if i>0: #去除第一行表頭
digit=str(content[i]).find(findstring) #查找每一行中findstring的第一個(gè)位置
restime = int(str(content[i])[2:digit]) #每行內(nèi)容轉(zhuǎn)換為字符串,使用切片截取字符串
endtime= int(str(content[i])[digit+2:digit+15])
restimelist.append(restime)
endtimelist.append(endtime)
logging.info('response time list is {}'.format(restimelist))
logging.info('end time list is {}'.format(endtimelist))
len_restime=len(restimelist)
def count_other_ave(start,end): #定義函數(shù),計(jì)算列表中other_ave之外的響應(yīng)時(shí)間平均數(shù)
restimelist_sort=sorted(restimelist[start:end]) #排序響應(yīng)時(shí)間
restimelist_num = len(restimelist_sort) #長(zhǎng)度
list_index = round(restimelist_num * other_ave / 100) # 計(jì)算第other_ave%的位置,round四舍五入取整
other_ave_result = round(sum(restimelist_sort[list_index:]) / (restimelist_num - list_index)) # 使用sum函數(shù)求和,除以剩余值的個(gè)數(shù)
otheravelist.append(other_ave_result) #插入other_ave之外的響應(yīng)時(shí)間平均數(shù)
return
for i in range(len_restime):
if (endtimelist[i]+10000)<endtimelist[-1]: #結(jié)束時(shí)間+10000毫秒
for j in range(i,len_restime): #從第i位開(kāi)始,到最后
if endtimelist[j]>=(endtimelist[i]+10000): #從第i位開(kāi)始,到最后,判斷結(jié)束時(shí)間大于10S后的位置。
startindex=i
endindex=j
if i%1000==0: #根據(jù)樣本數(shù),選擇性來(lái)記錄下endtime的開(kāi)始和結(jié)束位置
logging.info('Endtime index begin at {},finish at {}'.format(startindex,endindex))
count_other_ave(startindex,endindex) #計(jì)算響應(yīng)時(shí)間列表中other_ave之外的響應(yīng)時(shí)間平均數(shù)
othertimelist.append(endtimelist[j])
break #計(jì)算一次,跳出循環(huán)
else:
count_other_ave(i,len_restime)
othertimelist.append(endtimelist[j])
break #當(dāng)結(jié)束時(shí)間第一個(gè)和最后一個(gè)差距不超過(guò)10S,計(jì)算一次,跳出循環(huán)
logging.info('P{} list is {}'.format(other_ave,otheravelist))
print('The length of p{} list is {}'.format(other_ave,len(otheravelist)))
print('The p{} list is {}'.format(other_ave,otheravelist))
othertimelist_relative=(np.array(othertimelist)-othertimelist[0]).tolist() #先把list變成array,進(jìn)行減法或者加法操作,再把a(bǔ)rray變成list
logging.info('end time list relative is {}'.format(othertimelist_relative))
#繪圖開(kāi)始
plt.figure(figsize=(8,4)) #創(chuàng)建繪圖對(duì)象,figsize參數(shù)可以指定繪圖對(duì)象的寬度和高度,單位為英寸,一英寸=80px
plt.plot(othertimelist_relative,otheravelist,"b--",linewidth=1) #在當(dāng)前繪圖對(duì)象中畫(huà)圖(x軸,y軸,藍(lán)色虛線,畫(huà)線寬度)
plt.xlabel("Time(ms)") #X軸的文字
plt.ylabel("ave_res_time") #Y軸標(biāo)簽
plt.title("P{} Line plot".format(other_ave)) #圖標(biāo)題
#plt.show() #顯示圖
plt.savefig("F:/99.practice/paixu/line.png") #保存圖
繪圖函數(shù)詳細(xì)實(shí)例可以參考:https://www.jb51.net/article/130979.htm
總結(jié)
以上是生活随笔為你收集整理的性能测试中P99的计算的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: autoCAD如何绘制多段体
- 下一篇: WINDOWS系统安装JAVA(详细版)