激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 一文搞懂JMeter engine中HashTree的配置問題

一文搞懂JMeter engine中HashTree的配置問題

2021-12-18 14:51HenryXiao8080 Java教程

本文主要介紹了JMeter engine中HashTree的配置,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

一、前言

  • 之前介紹了JMeter engine啟動原理,但是里面涉及到HashTree這個類結構沒有給大家詳細介紹,這邊文章就詳細介紹JMeter engine里面的HashTree結構具體用來做什么
  • 大家看到下面是JMeter控制臺配置截圖,是一個標準的菜單形式;菜單形式其實就類似于“樹型”的數據結構,而HashTree其實就是一個樹型數據結構

一文搞懂JMeter engine中HashTree的配置問題

我們在JMeter控制臺導出的jmx文件,是一個xml結構的數據,他其實就是由HashTree生成的,后面我們會講到

一文搞懂JMeter engine中HashTree的配置問題

 

二、HashTree的用法

首先通過HashTree類介紹,它一個集合類;具備Map結構的功能,而且是一種樹型結構

/**
* This class is used to create a tree structure of objects. Each element in the
* tree is also a key to the next node down in the tree. It provides many ways
* to add objects and branches, as well as many ways to retrieve.
* <p>
* HashTree implements the Map interface for convenience reasons. The main
* difference between a Map and a HashTree is that the HashTree organizes the
* data into a recursive tree structure, and provides the means to manipulate
* that structure.
* <p>
* Of special interest is the {@link #traverse(HashTreeTraverser)} method, which
* provides an expedient way to traverse any HashTree by implementing the
* {@link HashTreeTraverser} interface in order to perform some operation on the
* tree, or to extract information from the tree.
*
* @see HashTreeTraverser
* @see SearchByClass
*/
public class HashTree implements Serializable, Map<Object, HashTree>, Cloneable {
}

JMeter常用的HashTree方法(以下圖配置為例)

一文搞懂JMeter engine中HashTree的配置問題

//ListedHashTree是HashTree的繼承類,可以保證HashTree的順序性
HashTree tree = new ListedHashTree();
//TestPlan對象,測試計劃
TestPlan plan = new TestPlan();
//ThreadGroup對象,線程組
ThreadGroup group = new ThreadGroup();
//創建線程組數結構的對象groupTree
HashTree groupTree = new ListedHashTree();
//表示取樣器中的HTTP請求
HTTPSamplerProxy sampler = new HTTPSamplerProxy();
//創建HTTP請求的數結構對象samplerTree
//調用put方法相當于在plan(測試計劃)菜單對象下添加group(線程組)子菜單,這樣就形成了一種樹型結構
HashTree samplerTree = new ListedHashTree();
samplerTree.put(sampler,new ListedHashTree())
//groupTree樹結構添加子樹samplerTree
groupTree.put(group,samplerTree)
//tree樹結構為測試計劃對象,添加子樹groupTree,這樣就形成了上圖的層級形式
tree.put(plan, groupTree)
//調用add方法相當于在tree菜單對象下添加同級菜單
tree.add(Object key)

 

三、JMeter源碼導出jmx腳本文件介紹

首先在JMeter控制臺所有點擊事件,都會被ActionRouter中performaAction方法進行監聽執行,點擊導出按鈕,會進入到如圖方法通過反射由Save類執行

一文搞懂JMeter engine中HashTree的配置問題

在Save類中執行doAction主要是獲取到配置的HashTree

一文搞懂JMeter engine中HashTree的配置問題

當你點擊保存的時候,它會創建一個空文件,此時文件沒有任何內容

一文搞懂JMeter engine中HashTree的配置問題Save

類的doAction方法最后會調用backupAndSave(e, subTree, fullSave, updateFile)這個是來將創建的空文件寫入xml內容的

一文搞懂JMeter engine中HashTree的配置問題

SaveService中saveTree方法,其中JMXSAVERXStream對象,對應的maven坐標如下

<!-- https://mvnrepository.com/artifact/com.thoughtworks.xstream/xstream -->
<dependency>
  <groupId>com.thoughtworks.xstream</groupId>
  <artifactId>xstream</artifactId>
  <version>1.4.15</version>
</dependency>

一文搞懂JMeter engine中HashTree的配置問題

 

四、自定義HashTree生成JMeter腳本

首先maven引入以下幾個坐標<jmeter.version>5.3</jmeter.version>

      <dependency>
          <groupId>org.apache.jmeter</groupId>
          <artifactId>ApacheJMeter_http</artifactId>
          <version>${jmeter.version}</version>
          <exclusions>
              <exclusion>
                  <groupId>org.apache.logging.log4j</groupId>
                  <artifactId>log4j-slf4j-impl</artifactId>
              </exclusion>
          </exclusions>
      </dependency>
      <dependency>
          <groupId>org.apache.jmeter</groupId>
          <artifactId>ApacheJMeter_functions</artifactId>
          <version>${jmeter.version}</version>
      </dependency>
      <dependency>
          <groupId>org.apache.jmeter</groupId>
          <artifactId>ApacheJMeter_jdbc</artifactId>
          <version>${jmeter.version}</version>
      </dependency>

      <dependency>
          <groupId>org.apache.jmeter</groupId>
          <artifactId>ApacheJMeter_tcp</artifactId>
          <version>${jmeter.version}</version>
      </dependency>

先創建一個取樣器,然后寫成HashTree的數據結構

public static ThreadGroup threadGroup;
//創建一個標準的線程組
private static void initThreadGroup(){
  LoopController loopController = new LoopController();
  loopController.setName("LoopController");
  loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
  loopController.setProperty(TestElement.GUI_CLASS, JMeterUtil.readSaveProperties("LoopControlPanel"));
  loopController.setEnabled(true);
  loopController.setLoops(1);
  ThreadGroup group = new ThreadGroup();
  group.setEnabled(true);
  group.setName("ThreadGroup");
  group.setProperty(TestElement.TEST_CLASS, JMeterUtil.readSaveProperties("ThreadGroup"));
  group.setProperty(TestElement.GUI_CLASS, JMeterUtil.readSaveProperties("ThreadGroupGui"));
  group.setProperty(ThreadGroup.ON_SAMPLE_ERROR,"continue");
  group.setProperty(ThreadGroup.IS_SAME_USER_ON_NEXT_ITERATION,true);
  group.setProperty(TestElement.COMMENTS,"");
  group.setNumThreads(1);
  group.setRampUp(1);
  group.setDelay(0);
  group.setDuration(0);
  group.setProperty(ThreadGroup.ON_SAMPLE_ERROR, ThreadGroup.ON_SAMPLE_ERROR_CONTINUE);
  group.setScheduler(false);
  group.setSamplerController(loopController);
  threadGroup = group;
}

創建一個標準的線程組

public static ThreadGroup threadGroup;
//創建一個標準的線程組
private static void initThreadGroup(){
  LoopController loopController = new LoopController();
  loopController.setName("LoopController");
  loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
  loopController.setProperty(TestElement.GUI_CLASS, JMeterUtil.readSaveProperties("LoopControlPanel"));
  loopController.setEnabled(true);
  loopController.setLoops(1);
  ThreadGroup group = new ThreadGroup();
  group.setEnabled(true);
  group.setName("ThreadGroup");
  group.setProperty(TestElement.TEST_CLASS, JMeterUtil.readSaveProperties("ThreadGroup"));
  group.setProperty(TestElement.GUI_CLASS, JMeterUtil.readSaveProperties("ThreadGroupGui"));
  group.setProperty(ThreadGroup.ON_SAMPLE_ERROR,"continue");
  group.setProperty(ThreadGroup.IS_SAME_USER_ON_NEXT_ITERATION,true);
  group.setProperty(TestElement.COMMENTS,"");
  group.setNumThreads(1);
  group.setRampUp(1);
  group.setDelay(0);
  group.setDuration(0);
  group.setProperty(ThreadGroup.ON_SAMPLE_ERROR, ThreadGroup.ON_SAMPLE_ERROR_CONTINUE);
  group.setScheduler(false);
  group.setSamplerController(loopController);
  threadGroup = group;
}

創建一個標準的測試計劃

public static TestPlan testPlan;
//創建一個標準的測試計劃
private static void initTestPlan() {
  TestPlan plan = new TestPlan();
  //設置測試計劃屬性及內容,最后都會轉為xml標簽的屬性及內容
  plan.setProperty(TestElement.NAME, "測試計劃");
  plan.setProperty(TestElement.TEST_CLASS, JMeterUtil.readSaveProperties("TestPlan"));
  plan.setProperty(TestElement.GUI_CLASS, JMeterUtil.readSaveProperties("TestPlanGui"));
  plan.setEnabled(true);
  plan.setComment("");
  plan.setFunctionalMode(false);
  plan.setTearDownOnShutdown(true);
  plan.setSerialized(false);
  plan.setProperty("TestPlan.user_define_classpath","");
  plan.setProperty("TestPlan.user_defined_variables","");
  plan.setUserDefinedVariables(new Arguments());
  testPlan = plan;
}

開始封裝成一個HashTree的配置

//先創建一個測試計劃hashtree對象
HashTree hashTree = new ListedHashTree();
//在創建一個線程組threaddGroupTree對象
HashTree threadGroupTree = new ListedHashTree();
//HttpRequestConfig為HTTP對應的請求頭、請求體等信息數據,傳入httpToHashTree靜態方法獲取到取樣器的HashTree數據結構,源碼上圖已分享
HashTree httpConfigTree = XXClass.httpToHashTree(HttpRequestConfig httpRequestData)
//threadGroupTree添加子菜單httpConfigTree對象
threadGroupTree.put(group, httpConfigTree);
//測試計劃hashTree添加子菜單threadGroupTree對象
hashTree.put(JMeterTestPlanConfigService.testPlan, threadGroupTree);

HashTree寫好后,調用JMeter原生方法SaveService.saveTree(hashTree,outStream);生成對應的xml

如果直接調用的話生成的xml格式會形成如下圖所示,而非JMeter原生導出jmx形式,這種文件結構JMeter控制臺讀取會報錯,識別不了

一文搞懂JMeter engine中HashTree的配置問題

一文搞懂JMeter engine中HashTree的配置問題

后面閱讀SaveService源碼才明白,生成xml文件之前會先初始化靜態代碼塊內容,初始化屬性

一文搞懂JMeter engine中HashTree的配置問題
一文搞懂JMeter engine中HashTree的配置問題

過程中會調用JMeterUtils中的findFile方法來尋找saveservice.properties文件

一文搞懂JMeter engine中HashTree的配置問題

由于SaveService 中都是靜態方法無法重寫,所以根據最后調用JMeterUtils中的findFile方法來尋找saveservice.properties有兩種解決方案

方案一 :不推薦,在項目根目錄下存放saveservice.properties,這樣findFile方法就能拿到,但是這樣不好,因為maven打包的時候該文件會打不進去,至少我springboot項目是遇到這樣的問題

方案二:推薦,創建一個臨時文件命名為saveservice.properties,然后提前將saveservice.properties配置讀取到臨時文件中,這樣在調用JMeterUtils中的findFile方法同樣能夠找到配置,成功解決SaveService初始化屬性導致的問題,具體代碼如下

private void hashTreeToXML(HashTree hashTree,PressureConfigInfo configInfo){
  FileOutputStream outStream = null;
  File file = new File("temp.jmx");
  File tempFile = null;
  try {
  	//創建一個臨時的saveservice.properties文件
      tempFile = new File("saveservice.properties");
      InputStream is = JMeterUtil.class.getResource("/jmeter/saveservice.properties").openStream();
      //將配置文件寫入臨時文件中
      FileUtil.writeFromStream(is,tempFile);
      outStream = new FileOutputStream(file);
      //調用saveTree成功轉為xml
      SaveService.saveTree(hashTree,outStream);
      String xmlContent = FileUtil.readUtf8String(file);
      configInfo.setFile(xmlContent.getBytes());
  } catch (IOException e) {
      e.printStackTrace();
  }finally {
      try {
          FileUtils.forceDelete(file);
          FileUtils.forceDelete(tempFile);
      } catch (IOException e) {
          e.printStackTrace();
      }
  }
}

最后生成的xml文件結構如下圖,通過JMeter控制臺也能成功打開識別

一文搞懂JMeter engine中HashTree的配置問題

到此這篇關于一文搞懂JMeter engine中HashTree的配置問題的文章就介紹到這了,更多相關JMeter engine中HashTree配置內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/weixin_40686603/article/details/114589428

延伸 · 閱讀

精彩推薦
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7482021-02-04
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
主站蜘蛛池模板: 性 毛片 | 91视频第一页 | 日韩视频一区二区在线观看 | 亚洲成人福利电影 | 午夜国内精品a一区二区桃色 | 黄色影院在线观看视频 | 欧美一区在线观看视频 | 成人性视频欧美一区二区三区 | 一区二区三区国产视频 | 久精品国产 | 91黄瓜视频 | 国产美女爽到喷白浆的 | 三人弄娇妻高潮3p视频 | 亚洲精华液久久含羞草 | 亚洲第一黄色网 | 久久久成人精品视频 | 性色av一区二区三区在线观看 | 久久美女免费视频 | 成人区精品一区二区婷婷 | 日韩黄在线观看 | 久久艹综合| 黑人一区二区三区四区五区 | 国产黄网| 99精品视频网站 | 91九色网 | 久久资源总站 | 日日鲁夜夜视频热线播放 | 黄色免费在线网站 | 久久亚洲精品视频 | 久久久久久久久久久亚洲 | 欧美亚洲国产成人综合在线 | 毛片在线视频观看 | 国产精品一区二区羞羞答答 | 日韩激情一区 | 日本中文视频 | 在线视频成人永久免费 | 懂色av懂色aⅴ精彩av | 一级电影免费 | 久久国产亚洲精品 | 国产精品久久久久久久久久久久久久久久 | 快播av在线 |