每周讀書與學(xué)習(xí)是由清華大學(xué)出版社出版的《JMeter核心技術(shù)、性能測試與性能分析》一書的作者推出,分享作者多年的IT從業(yè)經(jīng)歷,希望對很多計算機科學(xué)技術(shù)IT類專業(yè)畢業(yè)生以及IT從業(yè)者有所幫助。
1、前置處理器
在Jmeter中,前置處理器即預(yù)處理器,用于在實際取樣器(Sampler)發(fā)出請求之前對即將發(fā)出的請求進行初始化的預(yù)處理,如下圖所示。

從圖中可以看到前置處理器通常包括:
JSR223 預(yù)處理程序:指的是使用JSR223規(guī)范(全稱為Java Specification Request 223,是一個Java語言平臺發(fā)布的規(guī)范,用于提供一種標(biāo)準(zhǔn)化的方式來嵌入腳本語言到Java應(yīng)用程序中)實現(xiàn)的一種預(yù)處理程序,該預(yù)處理程序中可以使用多種腳本語言,如下所示:
BeanShell:是使用Java語言實現(xiàn)的一個免費小型的支持嵌入的面向?qū)ο蟮哪_本語言。
Bsh:是BeanShell的簡寫,該腳本語言功能和BeanShell一致。
EcmaScript:是由ECMA國際(全稱為European Computer Manufacturers Association,即歐洲計算機制造商協(xié)會)通過ECMA-262標(biāo)準(zhǔn)設(shè)計的一種腳本語言,我們經(jīng)常使用的JavaScript腳本語言就是對EcmaScript標(biāo)準(zhǔn)的一種擴展實現(xiàn)。
Groovy:是一種運行在JVM(Java 虛擬機)上面向?qū)ο缶幊痰哪_本語言,Groovy既支持面向?qū)ο笠仓С肿鳛橐环N純粹的腳本語言來使用,在使用時,可以和Java語言之間互相引用和調(diào)用,由于Jmeter自身是通過Java語言實現(xiàn)的,所以很容易就能支持Groovy腳本語言的嵌入。
Java:目前使用最廣泛的一種面向?qū)ο蟮木幊陶Z言,Jmeter 自身就是通過Java語言實現(xiàn)的,所以預(yù)處理程序肯定會支持Java語言的編寫。
JavaScript:是目前使用最廣泛的一種動態(tài)解析和執(zhí)行的腳本語言,通常廣泛的應(yīng)用于前端網(wǎng)頁的開發(fā)中,是Web開發(fā)的核心語言。
Jexl:是Java Expression Language的簡寫,是一種表達型的語言。
Jexl2:是Jexl語言的2.0版本。
用戶參數(shù):用戶參數(shù)是一個對每個線程做預(yù)處理的動態(tài)賦值以便在性能測試時使用這些值,在Jmeter中,每個線程其實就是一個并發(fā)用戶。
HTML鏈接解析器:指的是自動處理 HTML 響應(yīng),解析出其中所有的HTML鏈接和表單, 以便在下一個HTTP取樣器中使用,通常當(dāng)在一個性能測試中同時存在同個HTTP取樣器時會被使用到,如下圖所示。

HTTP URL 重寫修飾符:和HTML鏈接解析器類似,但是其支持對HTTP URL進行重寫以便存儲會話ID來替代存儲Cookies,通??梢栽诰€程組中添加這個元件,只需要在此元件上指定會話id參數(shù)的名稱,該元件就可以在頁面中自動找到該參數(shù),并且將該參數(shù)添加到每個取樣器的請求中,該元件包含的其他功能如下:
路徑擴展:通過添加分號和會話id參數(shù)來重寫URL。
Do not use equals in path extension:表示在參數(shù)名稱和值之間不使用“=”符號的情況下需要重寫URL。
Do not use questionmark in path extension:表示不讓查詢字符串最終出現(xiàn)在路徑擴展中。
緩存會話Id:表示當(dāng)會話Id不存在時,是否應(yīng)該保存會話Id的值以供后續(xù)測試使用。
URL Encode:寫入?yún)?shù)是否進行URL編碼處理。
JDBC 預(yù)處理程序:JDBC預(yù)處理程序指的是在取樣器發(fā)出請求之前,可以通過JDBC的方式來運行一些SQL語句,這些SQL語句可以直接操作數(shù)據(jù)庫,比如使用取樣器發(fā)出請求之前,需要先查詢數(shù)據(jù)庫來獲取請求的參數(shù)或者是取樣器發(fā)出請求之前需要先向數(shù)據(jù)庫中構(gòu)造一些初始數(shù)據(jù)或者刪除一些已經(jīng)存在的數(shù)據(jù)等,如下圖所示。

正則表達式用戶參數(shù):指的是使用正則表達式的方式從上一個HTTP取樣器請求的響應(yīng)結(jié)果中提取HTTP參數(shù)指定的動態(tài)值以用于下一個HTTP取樣器作為請求參數(shù)使用,正則表達式用戶參數(shù)只特定于單個線程中傳遞使用,如下圖所示。

正則表達式用戶參數(shù)主要包容如下功能:
Regular Expression Reference Name:表示正則表達式引用的名稱。
Parameter names regexp group number:表示用于提取參數(shù)名稱的正則表達式的組號。
Parameter values regex group number:用于提取參數(shù)值的正則表達式的組號。
如下圖所示,展示的是一個從上一個HTTP取樣器請求的響應(yīng)結(jié)果中提取數(shù)據(jù)來作為下一個HTTP取樣器請求的參數(shù)的過程,在圖中可以看到:
當(dāng)需要從上一個HTTP取樣器的響應(yīng)結(jié)果中提取數(shù)據(jù)時,需要先為上一個HTTP取樣器創(chuàng)建一個后置處理器,后置處理器類型選擇為正則表達式提取器,關(guān)于后置處理器,我們將會在接下來的內(nèi)容詳細講解,后置處理器通常是在取樣器之后才會運行。
為下一個HTTP取樣器創(chuàng)建一個前置的正則表達式用戶參數(shù)元件,該元件用于接收上面正則表達式提取的結(jié)果數(shù)據(jù),并且按照規(guī)則提取參數(shù)名稱和參數(shù)值。
下一個HTTP取樣器使用提取的參數(shù)名稱和參數(shù)值來發(fā)出下一個HTTP取樣器的請求。

取樣器超時:用于設(shè)置取樣器的超時時長,單位為毫秒,當(dāng)取樣器超時此時長時會中斷取樣器的執(zhí)行,當(dāng)設(shè)置為0或者負數(shù)時,表示設(shè)置的時長為無限大,永遠不會超時。
BeanShell 預(yù)處理程序:使用BeanShell腳本語言來編寫取樣器的預(yù)處理程序,界面上主要包含如下功能:
每次調(diào)用前重置bsh.Interpreter重置解釋器:如果設(shè)置這個選項為True代表每次調(diào)用前都會重新創(chuàng)建解釋器,默認為False,通常不需要進行修改。
傳遞給BeanShell的參數(shù):用于設(shè)置傳遞給BeanShell腳本的參數(shù),可以以單個字符串的形式傳遞參數(shù)也可以以字符串?dāng)?shù)組的形式傳遞參數(shù)。
腳本文件名:設(shè)置要運行的BeanShell腳本的文件路徑以及名稱,通常如果是使用外部的腳本文件時,可以使用這個設(shè)置。
Script:直接在Jmeter界面中編寫腳本。
2、定時器
在Jmeter中,定時器類似于LoadRunner中的思考時間(think time),用來設(shè)置線程的延遲和同步時間,如下圖所示,通常是在每個取樣器發(fā)出請求之前執(zhí)行,定時器主要是有時候為了讓一個線程(并發(fā)用戶)的操作更加符合真實的人工使用場景,比如人在點擊某個系統(tǒng)中的某個界面按鈕或者打開某個頁面時,都會存在思考時間或者操作的延遲時間。
從圖中可以看到,定時器主要包括:
固定定時器:用于設(shè)置每個線程在發(fā)起取樣器請求之前等待相同的一段時長,此時長的單位為毫秒。
統(tǒng)一隨機定時器:用于設(shè)置每個線程在發(fā)起取樣器請求之前隨機等待一段時長,時長的單位為毫秒。
Constant Throughput Timer:又叫常數(shù)吞吐量定時器,顧名思義就是根據(jù)設(shè)置的吞吐量的值來控制線程的運行延遲。可以通過設(shè)置每分鐘的吞吐量來控制線程的延遲,比如設(shè)置1分鐘內(nèi)的吞吐量為30,那么如果在1分鐘內(nèi)已經(jīng)達到30的吞吐量后,線程就會暫停發(fā)起取樣器請求,直到下一分鐘開始,線程才會繼續(xù)發(fā)送請求。計算吞吐量的方式包括只有此線程、所有活動線程、當(dāng)前線程組中的所有活動線程、所有活動線程(共享)、當(dāng)前線程組中的所有活動線程(共享)。
Precise Throughput Timer:又叫準(zhǔn)確的吞吐量定時器,和Constant Throughput Timer有點類似,可以準(zhǔn)確的根據(jù)設(shè)置的每個吞吐量周期下的目標(biāo)吞吐量來控制線程發(fā)起取樣器請求的延遲時長,該定時器主要包含如下參數(shù):
目標(biāo)吞吐量(每個“吞吐期”的樣本):設(shè)置每個“吞吐量周期”要從所有受影響的采樣器請求中獲取的最大吞吐量,該設(shè)置會包括線程組中的所有線程的吞吐量之和。
吞吐量周期(秒):設(shè)置統(tǒng)計吞吐量的周期時長,單位為秒。
測試持續(xù)時間(秒):用于設(shè)置本次吞吐量定時器運行的持續(xù)時長,單位為秒。
批處理離開-批處理中的線程數(shù)(線程):用于設(shè)置批處理中的線程數(shù)量。
批處理離開-批處理中的線程之間的延遲(ms):用于設(shè)置批處理中線程之間的延遲時長,單位為毫秒。
隨機種子(從0變?yōu)殡S機):設(shè)置隨機數(shù)生成的種子值,默認為0,表示完全隨機。

高斯隨機定時器:用于設(shè)置每個線程在發(fā)起取樣器請求之前隨機等待一段時長,可以指定該時長的偏差范圍,由于該定時器的偏差變化符合高斯曲線分布,所以命名為高斯隨機定時器。
JSR223 Timer:指的是使用JSR223(全稱為Java Specification Request 223,是一個Java語言平臺發(fā)布的規(guī)范)腳本語言來生成線程延遲,在JSR223 Timer中支持的腳本語言包括groovy、java、javascript、jexl等,和JSR223 預(yù)處理程序類似,JSR223 Timer同時也支持將參數(shù)傳遞給腳本作為參數(shù)來使用。
泊松隨機定時器:和統(tǒng)一隨機定時器很類似,同樣也是用于設(shè)置每個線程在發(fā)起取樣器請求之前隨機等待一段時長,時長的單位為毫秒,和統(tǒng)一隨機定時器不同的是,泊松隨機定時器的延遲時長通常都發(fā)生在一個特定值的附近,彼此相差不會很大并且符合泊松分布,所以又叫泊松隨機定時器。
Synchronizing Timer:又叫同步定時器,是一種阻塞型的定時器,其目的主要用于設(shè)置每次阻塞到指定的線程數(shù)量后再一次釋放所有的阻塞的線程去同時發(fā)起取樣器請求,有點類似LoadRunner中的集合點(或者又叫同步點)。相當(dāng)于是讓指定的數(shù)量的線程同時達到了可執(zhí)行狀態(tài)后,再同時去發(fā)起取樣器請求,如下圖所示。

Synchronizing Timer主要包含如下兩個參數(shù)配置:
模擬用戶組的數(shù)量:用于設(shè)置每次讓多少個線程進行阻塞以達到統(tǒng)一執(zhí)行的狀態(tài)。
超時時間以毫秒為單位:用于設(shè)置等待的時長以讓所有的線程達到可執(zhí)行的狀態(tài),如果超過這個時長后,指定的所有線程還沒有達到可執(zhí)行的狀態(tài),那么將不再繼續(xù)等待,會直接向下執(zhí)行。
BeanShell Timer:即BeanShell定時器,指的是使用自定義的BeanShell 腳本語言來生成線程延遲,和JSR223 Timer很類似,同時也支持將參數(shù)傳遞給腳本作為參數(shù)來使用。
3、本次學(xué)習(xí)總結(jié)
前置處理器的使用,包括JSR223 預(yù)處理程序、用戶參數(shù)、HTML鏈接解析器、HTTP URL 重寫修飾符、JDBC 預(yù)處理程序、正則表達式用戶參數(shù)、取樣器超時、BeanShell 預(yù)處理程序等,其中HTTP URL 重寫修飾符、JDBC 預(yù)處理程序、正則表達式用戶參數(shù)這三個前置處理器元件建議讀者們進行重點掌握。
定時器的使用,包括固定定時器、統(tǒng)一隨機定時器、Constant Throughput Timer、Precise Throughput Timer、高斯隨機定時器、JSR223 Timer、泊松隨機定時器、Synchronizing Timer、BeanShell Timer等,定時器通常適用于一些特殊的性能測試場景,用于模擬出更加真實的用戶需求,其中固定定時器、統(tǒng)一隨機定時器、高斯隨機定時器、Synchronizing Timer這幾個定時器元件建議讀者們進行重點掌握。
出處:本次學(xué)習(xí)的內(nèi)容參考自清華大學(xué)出版社出版的《JMeter核心技術(shù)、性能測試與性能分析》一書