系列1--jmetr包中的四个java文件

上一篇 / 下一篇  2017-06-18 04:34:20 / 个人分类:Jmeter源码系列

jmeter的启动文件在bin目录中,是个bat批处理文件,会设置一些环境变量和一些jvm的东东,我们暂且不去管它,跟代码没啥关系,还有一个重要的事情就是进入代码,入口就是org.apache.jmeter包中的NewDriver.java,org.apache.jmeter这个包中还有几个很重要的包,但直接包含的java文件只有四个,那么我们就先从NewDriver.java这个文件开始,以从上到下的方式对JMeter做一个代码学习的笔记吧。
  NewDriver.java
    这个类开始就有一个静态块,用于获取并设置jmeter的工作目录,以及将lib、ext、junit三个文件夹中的jar包加入到classpath中,然后创建了一个私有的构造方法,目的是防止被实例化。然后又提供了两个静态方法addURL和addPath,是向类装载器设置类路径而不修改系统classpath以及将两者都添加修改。这两个方法在这个类里面没有用到,是为用户设置jar路径做准备的,后面讲JMeter.java的private void updatePath(String property, String sep, boolean cp)时介绍。
   最后,既然是入口必然会有一个main函数了,比较简单,如果第一个参数是report就创建org.apache.jmeter.JMeterReport实例并调用其start方法;否则就创建org.apache.jmeter.JMeter实例并调用其start方法。后面主要以JMeter实例来进行研究。

  JMeter.java:
   这里面首先定义了很多启动选项,并且建立了选项较易理解的类,比如短形式-h  长形式-help 以及描述、互斥、是否必需、可选等。
   public void start(String[] args):获取命令行参数,并使用它们来确定如何启动JMeter。首先用CLArgsParser类解析选项,如果没有错误的话就判断是否有互斥的参数共存了,比如-R -X只能在非gui模式下使用。如果有错误就打印出来并返回。然后利用private void initializeProperties(CLArgsParser parser)方法来初始化很多属性文件和log文件的位置、JMeterHOME。然后将系统和java属性写入log;然后调用etProxy(parser)为JVM设置代理服务器,调用updateClassLoader()来更新类加载器。然后写入开始时间,设置版本,帮助等杂事。最后,读入测试文件(如果命令行中有的话),如果测试文件是LAST的话就读入最后一次使用的测试文件,读完文件后判断是否gui启动,如果是就调用startGui(testFile)启动并调用 startOptionalServers()来启动beanshell服务和镜像服务;否则调用startNonGui(testFile, jtlFile, rem)启动以及调用startOptionalServers()来启动beanshell服务和镜像服务。
   private void startGui(String testFile):在GUI模式中启动JMeter,主要就是把图形界面打开,如果有文件传进来就把文件显示到树中,如果文件为空,那么新建一个树,显示第一级元素(应该就是测试计划),然后把焦点放到第一级元素上面。
  private void updatePath(String property, String sep, boolean cp)提供这个函数将任意目录加入到Path中,第一个参数是jmx的属性名,第二个是分隔符,第三个是是否写入到系统classpath中,该函数会获取property所对应的值,然后用sep分割成目录,如果cp为真则NewDriver.addPath(path)即向类装载器设置类路径且修改系统classpath,否则调用NewDriver.addURL(path)向类装载器设置类路径而不修改系统classpath。这个方法是为private void updateClassLoader()服务的,他把search_paths、user.classpath、plugin_dependency_paths这三个更新到classloader中,如果需要的话。
   private void startNonGui(String testFile, String logFile, CLOption remoteStart):非GUI方式启动,先添加一个系统属性JMETER_NON_GUI为true,这样samplers就可以检查JMeter是否在非gui模式下运行。然后创建一个新的JMter实例,将原本的实例设置为新实例的parent;如果是远程启动则设置远程hosts,如果没有获取到hosts则设置为remote_hosts属的值,获取不到的话设为默认127.0.0.1。这个模式下testfile不能为空,否则抛异常;最后调用新实例的runNonGui方法,下面介绍。
   private void runNonGui(String testFile, String logFile, boolean remoteStart, String remote_hosts_string):在批处理模式下运行。首先读取测试文件并设置基础脚本目录;然后通过SaveService的loadTree方法将文件转化成tree;然后计算所有可替换控制器,然后转换测试树,将enable状态的testelement移除,以及将可替换控制器进行替换。如果有得话就添加摘要生成器如果有传入logfile,那么就把摘要生成器放到ResultCollector中并设置到tree的最上面位置;如果没有传入logfile就直接把摘要生成器Summariser放到tree的最上边。最后新建一个engine组,然后在树中最上边添加一个ListenToTest的实例,此实例作为监听测试用,如果是非远程模式就新建一个engine并调用engine.runTest(),并放入engine组中,远程模式暂时不讲。最后调用startUdpDdaemon来启动udp守护进程。
   ListenToTest静态类,在测试开始、结束时记录时间并对开始的测试计数。还定义了默认的图标;
     startUdpDdaemon(final List<JMeterEngine> engines):守护进程,如果jmeterengine.nongui.port大于1000,则循环的调用waitForSignals(engines, socket)。
   waitForSignals(final List<JMeterEngine> engines, DatagramSocket socket):用来获取命令,只接受本地主机的命令,如StopTestNow、Shutdown、HeapDump。

DynamicClassLoader.java:
   加载类的工具,把URLClassLoader的addURL()方法设置为public的了,新方法updateLoader可将url列表加到线程的类加载器中。可能跟线程安全有关。

ProxyAuthenticator.java:赋予JMeter使用需要用户名和密码的代理的能力。构造函数会初始化用户名和密码;方法PasswordAuthentication getPasswordAuthentication()使用构造函数中指定的用户名和密码返回一个PasswordAuthentication实例。

今天把jmeter包中仅有的四个java文件大致看了,明天继续看engine包里面的东西。

TAG: java JAVA Java

 

评分:0

我来说两句

日历

« 2024-04-21  
 123456
78910111213
14151617181920
21222324252627
282930    

数据统计

  • 访问量: 7950
  • 日志数: 7
  • 建立时间: 2016-09-11
  • 更新时间: 2017-06-18

RSS订阅

Open Toolbar