欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
為啥群里小伙伴都“消失”了?原來(lái)大家都在偷偷學(xué)習JMeter擴展開(kāi)發(fā)!

JMeter作為開(kāi)源性能測試工具,近年來(lái)社區發(fā)展活躍,業(yè)界應用廣泛,工具功能愈發(fā)完善成熟,成為領(lǐng)域內十分流行的性能測試工具之一。得益于開(kāi)源特性,JMeter具有得天獨厚的可靈活擴展性,用戶(hù)可根據實(shí)際功能需求和測試場(chǎng)景,對JMeter進(jìn)行自定義擴展開(kāi)發(fā)。

如何對更好地實(shí)現JMeter擴展開(kāi)發(fā)?本文先從核心源碼層入手,對JMeter啟動(dòng)、加載、運行的應用原理進(jìn)行解讀,涉及到NewDriver、JMeter、JMeterEngine、HashTree等相關(guān)內容。



1. 運行入口—NewDriver類(lèi)


NewDriver是整個(gè)JMeter 的入口類(lèi), 完整路徑是org.apache.JMeter.NewDriver。NewDriver類(lèi)中包括jar包掃描、命令解析、全局參數定義、類(lèi)加載器路徑操作等靜態(tài)方法,核心部分是main方法,main方法通過(guò)反射調用JMeter類(lèi),啟動(dòng)其start方法,通過(guò)對傳入參數的解析判斷是否執行GUI或NON_GUI模式,這里即區分了日常使用中的界面調試和命令行發(fā)壓兩種應用形態(tài)。需要注意的是,在日常應用中,GUI模式也就是界面模式由于存在大量的界面資源加載和元件數據監聽(tīng),尤其是監聽(tīng)器元件存在大量數據同步和更新,所以在編譯源碼啟動(dòng)JMeter時(shí)官方在日志中特別強調若要執行發(fā)壓工作,請務(wù)必使用命令行模式,否則會(huì )影響發(fā)壓效率和資源消耗。在實(shí)際使用中,筆者認為應綜合考慮測試場(chǎng)景,若存在小并發(fā)且對響應時(shí)間和TPS敏感度不高的場(chǎng)景,通過(guò)界面級操作發(fā)壓也非并不可。
在首次用IDE進(jìn)行源碼編譯時(shí),NewDriver會(huì )報錯“配置文件無(wú)法找到”的錯誤,原因是在NewDriver配置JMeter Home地址方法中,默認會(huì )把Parent目錄當做安裝根目錄,所以會(huì )存在無(wú)法找到properties文件而產(chǎn)生的錯誤。
所以通過(guò)編譯執行的源碼,在啟動(dòng)NewDriver時(shí)需首先在Run Configration中手動(dòng)配置JMeter.home參數。
-Djmeter.home='JMeter項目的根目錄(bin文件夾所在目錄)'
繼續看main函數,首先設置當前線(xiàn)程的類(lèi)加載器,隨后將啟動(dòng)命令參數中關(guān)于日志文件和日志類(lèi)型的字符做解析并配置好日志屬性。隨即進(jìn)入反射調用部分。代碼如下所示,主要是加載類(lèi)、獲取實(shí)例、獲取方法類(lèi)型、反射調用四個(gè)步驟。
// 加載JMeter類(lèi)
Class<?> initialClass = loader.loadClass('org.apache.JMeter.JMeter');
// 獲取JMeter類(lèi)實(shí)例
Object instance = initialClass.getDeclaredConstructor().newInstance();
// 獲取start方法類(lèi)型實(shí)例
Method startup = initialClass.getMethod('start', new Class[] { new String[0].getClass() });
// 反射調用JMeter類(lèi)的start方法
startup.invoke(instance, new Object[] { args });
此時(shí)關(guān)于JMeter配置方面的內容包括類(lèi)加載器、日志設置、系統環(huán)境變量、工具目錄等部分已經(jīng)完成,隨著(zhù)進(jìn)入JMeter實(shí)例的start方法,開(kāi)始執行更具體的資源加載、屬性更新、命令解析工作。


2. 邏輯操作—JMeter類(lèi)


JMeter類(lèi)由NewDriver入口類(lèi)通過(guò)反射調用,是實(shí)際的業(yè)務(wù)邏輯類(lèi),通過(guò)接收用戶(hù)啟動(dòng)參數進(jìn)行解析。JMeter 類(lèi)做的事情主要有四個(gè)方面。
1. 解析命令參數及加載配置文件。
2. 將 .JMX文件解析成 HashTree。
3. 實(shí)例化一個(gè)StandardJMeterEngine,并把測試的工作交給JMeterEngine。
4. 監聽(tīng)所有的 JMeterEngine,當接收到 GUI 的 StopTestNow / Shutdown 等命令時(shí),調用JMeterEngine接口相應的方法。
其中start方法是JMeter的重點(diǎn)部分。因為其承擔了傳入指令的第一步解析和對后續應用模式的邏輯判斷。
首先解析啟動(dòng)時(shí)候傳入的外部命令行參數并加載相應配置文件。
// 解析命令行參數
CLArgsParser parser = new CLArgsParser(args, options);
//初始化參數配置+初始化JMeter日志
initializeProperties(parser);
隨后執行updateClassLoader方法,把search_paths和user.classpath里面設置的 jar 文件添加到自定義的classloader 中,它的作用可以讓我們在某些場(chǎng)景下更方便使用JMeter。例如我們自定義的Java Sampler,理論上是要打包成 Jar 放到lib/ext 目錄下,但通過(guò)設置search_paths 和user.classpath的方式,利用本方法可以來(lái)簡(jiǎn)化操作,將自定義開(kāi)發(fā)中的Sampler放在不同位置。
//將jar文件添加到自定義的classloader中
updateClassLoader();
隨后根據傳入參數的解析結果,進(jìn)行兩個(gè)核心調用。
一個(gè)是啟動(dòng) GUI 的模式,即啟動(dòng)帶界面的工具模式。
傳入參數為JMX測試腳本文件路徑。在startGui中需進(jìn)行界面顯示資源的加載、布局監聽(tīng)的初始化、界面插件的裝配以及存儲結構初始化等一系列操作伴隨進(jìn)行,最后用戶(hù)通過(guò)界面面板進(jìn)行操作,觸發(fā)不同的監聽(tīng)事件執行不同的工具操作調用。GUI模式是腳本設計和測試調試期間應用的模式,有比較直觀(guān)的顯示效果,但因其中包含大量的監聽(tīng)事件以及數據資源更新,因此本模式下對宿主機資源消耗和發(fā)壓執行效率會(huì )有一定影響。
另一個(gè)是啟動(dòng)NON_GUI 模式,也就是日常使用的命令行執行動(dòng)作。
startNonGui 方法執行前,需進(jìn)一步對命令行參數進(jìn)行解析,包括遠程執行、日志文件、測試報告等,隨后向startNonGui 傳入對應參數并啟動(dòng)。startNonGui 中創(chuàng )建了一個(gè)新的JMeter 實(shí)例driver,在非分布式的場(chǎng)景下,調用執行runNonGui方法。
runNonGui解析腳本內容并生成HashTree結構保存,再根據remoteStart變量區分是否為 Remote 模式。以本地運行場(chǎng)景為例,JMeter會(huì )新建StandardJMeterEngine引擎實(shí)例,傳入已解析完成的HashTree數據結構,執行engine.runTest()啟動(dòng)新線(xiàn)程執行異步調用,并在將該引擎加入引擎列表中。
runNonGui方法最后調用的startUdpDdaemon(engines) 是一個(gè)JMeter管理服務(wù),傳入維護的引擎列表,用來(lái)管理 JMeter 的運行狀況,通過(guò)waitForSignals方法啟動(dòng)socket監聽(tīng),識別Shutdown/StopTestNow/HeapDump/ThreadDump等操作指令,這樣達到了JMeter對發(fā)壓引擎的管理。
在啟動(dòng)GUI和NON_GUI模式中,都執行了startOptionalServers()方法.這個(gè)方法的核心邏輯就是先在配置文件中讀取相關(guān) beanshell 的配置文件信息,然后調用Runnable t = new BeanShellServer(bshport, bshfile)來(lái)啟動(dòng)一個(gè)BeanShell服務(wù)。BeanShell 實(shí)際作用可以理解為對 runtime 的 JVM做一些動(dòng)態(tài)的調整,例如獲取JMeter變量,或者修改一些變量來(lái)改變最后JMeter 的運行行為等,以達到方便對 JMeter 進(jìn)程做一些動(dòng)態(tài)調整的目的。


3. 發(fā)壓引擎—JMeterEngine引擎接口


JMeterEngine是發(fā)壓引擎接口,具體實(shí)現為StandardJMeterEngine 。JMeterEngine中主要定義了引擎的操作方法,包括配置HashTree、執行測試、停止測試、設置屬性和引擎狀態(tài)識別等。JMeterEngine 依賴(lài)于由 JMX文件解析而來(lái)的 HashTree ,每一個(gè) JMeter 測試計劃都會(huì )對應一個(gè) JMX文件。所以只要能合理的定義各測試組件并組裝起來(lái),按規則生成JMX文件,就可通過(guò) JMeterEngine 壓測引擎去執行測試任務(wù)而不用依賴(lài)JMeter工具本身,這也是調用發(fā)壓引擎隱式開(kāi)展發(fā)壓操作的新方向。JMeterEngine 引擎接口定義如下所示。
StandardJMeterEngine是本地單機版本JMeter進(jìn)行發(fā)壓操作的實(shí)際處理類(lèi)。StandardJMeterEngine 還實(shí)現了Runnable接口,在StandardJMeterEngine的runTest()的實(shí)現中可以發(fā)現,this作為參數放置到了Thread進(jìn)行調用,所以StandardJMeterEngine 自身會(huì )是多線(xiàn)程執行的模式。
runTest()中啟動(dòng)thread,會(huì )進(jìn)入其run方法正式開(kāi)始執行測試腳本。在run方法中的JMeterContextService.startTest()是用來(lái)設置運行啟動(dòng)的狀態(tài)。JMeterContextService 是在整個(gè)JMeter的線(xiàn)程之間是共享的,但其中的threadContext 的變量屬于ThreadLocal獨享,也就是每個(gè)線(xiàn)程獨享。
運行狀態(tài)和HashTree數據遍歷完成后,用Setup Thread Group 啟動(dòng) N 個(gè)線(xiàn)程組來(lái)做初始化,隨后主動(dòng)觸發(fā)JMeterUtils.helpGC()動(dòng)作,緊接著(zhù)開(kāi)始執行測試的Abstract Thread Group和最后的Post Thread Group 。在線(xiàn)程組的操作中都是根據腳本中設置的線(xiàn)程組數量進(jìn)行循環(huán)操作,每個(gè)循環(huán)內部是一個(gè)線(xiàn)程組的執行操作,通過(guò)調用startThreadGroup方法將本線(xiàn)程組信息傳入,隨即啟動(dòng)group.start()開(kāi)始執行。
這些操作和Setup Thread Group 的調用都大同小異,因為實(shí)際執行發(fā)送請求和并發(fā)線(xiàn)程的管理都在 Thread Group 中,根據線(xiàn)程組設置的線(xiàn)程數量啟動(dòng)循環(huán)新建線(xiàn)程JMeterThread再調起具體發(fā)壓。
上文提到,StandardJMeterEngine僅是JMeterEngine的一種實(shí)現,它主要是實(shí)現了單機版本的發(fā)壓引擎功能。而JMeterEngine的另一個(gè)實(shí)現是分布式模式下的ClientJMeterEngine,其承擔Master角色對分布式測試任務(wù)進(jìn)行管理,這里不做詳細介紹。


4. 存儲結構—HashTree存儲結構

JMeter的測試腳本是JMX文件,其中保存了不同元件和變量的數據內容,可以用于在GUI 模式下加載整個(gè)測試組件,也可以直接運行于NON_GUI的執行模式,文件格式基于XML類(lèi)型。而HashTree則是在內部存儲文件信息的數據結構,是JMX文件在內存的一份映射。
HashTree將數據組織到一個(gè)遞歸樹(shù)結構中并提供了操作該結構的方法。HashTree數據結構設計的理論基礎是“質(zhì)數分辨定理”,簡(jiǎn)單來(lái)說(shuō)就是“n個(gè)不同質(zhì)數可以分辨的連續整數的個(gè)數和這些質(zhì)數的乘積相等”,分辨是指連續整數不可能有完全相同的余數序列。HashTree保證每層節點(diǎn)的子節點(diǎn)個(gè)數為連續質(zhì)數,因此HashTree是動(dòng)態(tài)的,子節點(diǎn)可以隨意創(chuàng )建,而由于結構本身是一個(gè)單項增加結構,所以這種結構會(huì )隨著(zhù)存儲量的增加而不斷增大。在JMeter中,HashTree用于創(chuàng )建測試對象的樹(shù)結構,樹(shù)中每一個(gè)元素也是下一個(gè)節點(diǎn)的鍵。利用HashTree在十次比較之內即可查找到目標對象是否存在,可以進(jìn)行快速匹配和查找,效率可觀(guān)。
觀(guān)察JMX文件可知測試腳本是具有格式要求的,每一層都只有2個(gè)類(lèi)型的節點(diǎn)
1. Object 節點(diǎn) - 代表一個(gè) Test Component。
2. HashTree - 一個(gè)HashTree 的子節點(diǎn)。
查看org.apache.jorphan.collections.HashTree 這個(gè)類(lèi)的定義可以發(fā)現本結構核心存儲就是一個(gè)protected final Map<Object, HashTree> data 的 Map ,通過(guò)對外提供Map 接口來(lái)給上層提供讀寫(xiě)的能力。ListedHashTree 是HashTree的子類(lèi),在startThreadGroup具體執行線(xiàn)程組操作實(shí)際是將HashTree向下轉型為子類(lèi)ListedHashTree對象,利用到其順序特性 。
JMeter在HashTree數據遍歷上采用了訪(fǎng)問(wèn)者設計模式,HashTreeTraverser定義了訪(fǎng)問(wèn)者的標準接口,實(shí)現解耦并提供更好靈活的擴展性。
SearchByClass 是訪(fǎng)問(wèn)者的實(shí)現,它主要實(shí)現了addNode方法,并且通過(guò)泛型定義了需要訪(fǎng)問(wèn)的Object 的類(lèi)型。
StandardJMeterEnginer的configure方法是獲取TestPlan的數據節點(diǎn),其中有利用訪(fǎng)問(wèn)者模式訪(fǎng)問(wèn)數據的實(shí)際代碼,可看出主要是借助HashTree 自身的 traverse方法,傳入通過(guò)TestPlan.class構造的新建SearchByClass 對象。最后使用testPlan.getSearchResults().toArray()獲取訪(fǎng)問(wèn)結果。
以HashTree為核心的JMeter數據存儲結構很好的確保運行時(shí)檢索數據的工作效率,在整個(gè)JMeter運行源碼中處處可見(jiàn)其身影,也是JMeter運行重要的存儲設計。
以上就是對JMeter核心源碼進(jìn)行的簡(jiǎn)單解讀。本次分享主要從JMeter啟動(dòng)運行角度,對重點(diǎn)的NewDriver類(lèi)、JMeter類(lèi)、JMeterEngine類(lèi)以及HashTree結構進(jìn)行了簡(jiǎn)單介紹,分析了內部組件的交互關(guān)系,展示了啟動(dòng)運行指令的執行鏈路,希望能對大家在擴展開(kāi)發(fā)JMeter的相關(guān)工作中提供一些思路和幫助。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Jmeter使用流程及簡(jiǎn)單分析監控
Jmeter寶典
下單接口調優(yōu)實(shí)戰,性能提高 10 倍
手把手教你配置和使用3款壓測工具 —— 沒(méi)壓測過(guò),面試都說(shuō)出來(lái)系統數據!
實(shí)現雙擊jmx文件打開(kāi)jmeter客戶(hù)端
input file : does not exist
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久