JMeter是一個優秀的開源專案,我們可以在jmeter的官網瞭解到如何使用和如何二次開發:https://jmeter.apache.org/
因工作需要,最近做了一個JMeter自定義的http元件(其實就是在http的基礎上加了點東西而已)。現就該需求為例,簡要地分享如何實現jmeter自定義元件。
我們先按照平常使用jmeter的思路,看看jmeter到底儲存了什麼東西?
可以看到,每一個元件都有一個guiclass和testclass。guiclass就是你能看到的頁面的程式碼,testclass就是你點選執行時後臺處理的程式碼。
Jmeter由多個模組組成,其中我們本次需要了解的是http模組。我們常用的「http請求」取樣器就是以HttpTestSampleGui+HTTPSamplerProxy(HTTPSamplerProxy為final類,故需繼承其父類別HTTPSamplerBase)組成。
注:圖片描述不是完全準確,僅就所需內容鋪排,大致瞭解即可。後續圖片亦然。
一般我們請求介面,需要在請求頭上新增token等簽名。而我本次需求,是在呼叫系統介面前,需要新增簽名到請求體,而這個簽名是使用系統門戶生成的key和access、時間戳、請求體等,通過某種演演算法生成的。
系統生成簽名分為兩個情況:
1、發起獲取session請求時,使用key、access、timestamp生成簽名。(獲取session在單執行緒組中只需要呼叫一次)
2、發起其他請求時,使用第一步獲取到的session、key、access、timestamp、請求體生成簽名。(其他請求可能呼叫多次)
那麼對於這個需求,我一開始的處理方法是:在「http請求」下,新增「前置處理器」,生成簽名。針對獲取session的請求還需要再新增「json提取器」提取session。
但這麼做發現我們新增的每一個請求都要新增「前置處理器」,實現同樣的邏輯程式碼。我們能不能提供一個新的元件,讓使用者在不改變原http請求的邏輯上,自動生成簽名呢?
我們可以在「http請求」的基礎上,通過繼承原生的HttpTestSampleGui和HTTPSamplerBase來實現自定義元件!
針對這個需求,我認為我們應該自定義兩個元件,分別處理獲取session請求和其他請求。使用者線上程組裡填入key、access,只需新增一個「PaimonSession請求」,請求後自動把介面返回的session存到這個執行緒組的公共變數裡(即jmeter的vars變數)。對於其他請求,使用者可以新增多個「Paimon請求」,填寫的內容與普通http請求一致。
這裡會引起另一個問題,就是如何設定key、access?一開始我們使用「使用者定義的變數」設定,但發現多個執行緒組的情況下,會出現後者覆蓋前者的情況,即無法做到每個執行緒組擁有獨立的key、access。所以能否在原生的http請求上新增兩個輸入框呢?
原生:
預期:
需求轉化:自定義兩個元件,兩個元件都需要在發起請求前生成簽名並新增到請求頭,其中一個元件需要新增兩個輸入框。
我們根據jmx檔案,分析原始碼。以contentEncoding為例,我們下載jmeter對應版本的原始碼,檢視HttpTestSampleGui檔案,在HttpTestSampleGui找不到contentEncoding這個變數。熟悉前端的同學可能會想到,前端一般會使用元件的形式達到程式碼複用的效果。這裡jmeter也是這樣實現的,guiclass是元件巢狀的。通過檢視原始碼,可以在HttpTestSampleGui找到UrlConfigGui,UrlConfigGui內出現了contentEncoding這個變數(其實在查詢原生元件的時候,我一般是偵錯jmeter原始碼)
所以除了繼承HttpTestSampleGui和HTTPSamplerBase,我們還需要繼承UrlConfigGui。
上面說到http請求的後端處理類是HTTPSamplerProxy,我們檢視HTTPSamplerProxy的程式碼,發現他其實就只實現了幾個方法。其中sample方法返回一個HTTPSampleResult物件,result大家都知道是結果的意思,所以大概率這個方法就是發起請求並得到結果(其實也可以debug知道,或者百度)。我們只需要繼承其父類別HTTPSamplerBase,同樣實現這些方法,並在sample方法裡生成簽名,新增到請求頭裡,再同樣發起請求,即可實現這個需求。
原生:
預期:
新建一個maven專案,pom引入jmeter_core與jmeter_http
按照需要繼承的類的路徑,在專案中新建目錄。剩下的步驟就是按以上分析的,新建並繼承對應的類,按需修改父類別方法,並建立關聯。
這裡特別說明一下增加輸入框的程式碼實現:首先繼承UrlConfigGui,然後參考UrlConfigGui的實現,增加key、access兩個欄位(需要注意的是,重寫方法需要先使用父類別的方法,再加上自定義的邏輯)
至於如何獲取自定義輸入框的值、如何獲取和設定系統變數、如何設定變數到請求頭等問題,可以私信問我拿原始碼
編寫好程式碼後,使用maven打包,並把jar包放到jmeter根目錄/lib/ext下。IDEA新增啟動設定,新增JAR Application,選擇jmeter根目錄/bin/ApacheJMeter.jar。儲存後,DEBUG啟動即可進行偵錯。
如果只是需要在本地使用,就可以像偵錯時一樣,直接把jar包放到jmeter根目錄/lib/ext下。
因我們公司使用Metersphere,所以需要修改MS打包jmeter映象的程式碼,新增自己的jar包,再重新打映象(需要注意的是,maven專案打包時預設不打依賴,而MS的jmeter映象缺少生成簽名需要的加密演演算法包,所以我在pom裡新增了maven-shade-plugin)