• 使用JMeter的Java Sampler轻松定制自己的benchmark


    做性能测试,接口测试,非常好

    转自  http://www.iteye.com/topic/1123432

    以前碰到更多的是WEB APP的性能测试,也许用得最多的是Loadrunner, Web Stress tool之类的常态化工具,从没考虑过对于后端引擎类的测试是怎样的。

    现在有幸主导了一个企业引擎的研发,其最关健的不是其功能如何,而是性能如何。故benchmark就显得尤为重要。

    既然是benchmark,一系列的性能监测、度量工具使用在所难免:

    1. nmon。首选的AIX/Linux性能监测工具。很多年前简单总结过,可参考:http://www.blogjava.net/itstarting/archive/2009/02/19/255638.html.

    2. jconsole。这个jdk自带的工具,监控JVM Heap size及回收、线程数量、CPU使用之类的,简单好用

    3. JMeter。这个Apache的老字号,不得不搬出来(公司没有Loadrunner,也不能盗版)

    4. Jamon。这个是方法级性能监控工具,完全无侵入性,如果框架用Spring,加上一小段AOP的配置即可

    没想到的是,最给我带来惊喜,还是JMeter.

    严格意义上上,JMeter我还是第一次在正式场合搬出来深度使用,以前简单的加压http,顶多算是个hello world.

    JMeter有很多的插件式的扩展,因为本引擎使用的Netty + Protobuf,所以自然想到的还是JUnit Sampler和Java Sample。其中JUnit Sample个人觉得没有Java Sampler好,姑且按下不表。

    Java Sampler,顾名思义,就是一个Java的采样器,扩展AbstractJavaSamplerClient即可轻松实现。

    1 public class Benchmark extends AbstractJavaSamplerClient {  
    2 ...  
    3 } 

    Benchmark有很多的场景,可以写很多个Benchmark类,比如Benchmark_A, Benchmark_B,我偷懒,四大场景我就写了一个。

    好了,下面重点说说需要实现的部分,及其作用。

    1. 重载getDefaultParameters方法。

    1 @Override  
    2 public Arguments getDefaultParameters(){  
    3         Arguments params = new Arguments();  
    4           
    5         //TODO: Right here to define/set parameters from GUI.  
    6           
    7         return params;  
    8 }  

    在这个方法里,可以设置各种参数,这些参数可以从GUI处获取,也可以设置合适的默认值。有意思的是,这些默认值在GUI扫描的时候,会自动出现在界面上,以供必要的调整和优化。

    2. 重载setupTest方法。

    1 @Override  
    2 public void setupTest(JavaSamplerContext arg0) {  
    3    //TODO: to init the test case, something like JUnit's setUp  
    4 }  

    为了达到真正的性能测试目的,所有的数据准备工作,应在这里完成。 需要注意的是,这个方法在JMeter初始化的每个线程都会执行一遍,而不是全局仅一遍。

    3. 重载并重点编写runTest方法。

    1 @Override  
    2 public SampleResult runTest(JavaSamplerContext arg0) {  
    3     //TODO: The load testing client side logic acting as the emulators puts here  
    4 }  

    这是我们重点要做编写的客户端代码,为Java Sampler实现的重点。

    在这里,你可以尽情的调用客户端的API,完成所需要与服务器端交互的一切,包括交易成功与否的判断。

    所谓代码胜千言,下面看看代码好了,加上了注释,就不用废话了:

     1 @Override  
     2 public SampleResult runTest(JavaSamplerContext arg0) {    
     3     SampleResult sp = new SampleResult(); //采样结果  
     4         MatchResponse matchResponse;  
     5         UUID uuid = UUID.randomUUID();  
     6         String key = uuid.toString();  
     7         sp.sampleStart();                                    //采用开始时间  
     8           
     9         //下面是客户端逻辑  
    10         try {            
    11             if("PC2-ID".equalsIgnoreCase(benchmark_mode)){  
    12                 matchResponse = client.sendMatchRequest(  
    13                             key,  
    14                             ENGINE.code(),   
    15                             pc2Image,   
    16                             sourcePositions,   
    17                             targetIdentifiers,   
    18                             ImageType.PC2.imageCode());  
    19             }else if("WSQ-ID".equalsIgnoreCase(benchmark_mode)){  
    20                 matchResponse = client.sendMatchRequest(  
    21                             key,  
    22                             ENGINE.code(),   
    23                             wsqImage,   
    24                             sourcePositions,   
    25                             targetIdentifiers,   
    26                             ImageType.WSQ.imageCode());  
    27             }else if("ID-ID".equalsIgnoreCase(benchmark_mode)){  
    28                 matchResponse = client.sendMatchRequest(  
    29                             key,  
    30                             ENGINE.code(),   
    31                             sourceIdentifier,   
    32                             sourcePositions,   
    33                             targetIdentifiers,   
    34                             ImageType.PC2.imageCode());  
    35             }else{  
    36                 print("Not supported benchmark mode found", benchmark_mode);  
    37                 throw new java.lang.IllegalArgumentException("Not supported benchmark mode found");  
    38             }  
    39   
    40             sp.sampleEnd(); //采用结束  
    41               
    42             this.printMatchResponse(matchResponse);  
    43   
    44             //set success flag to true but need to verify later  
    45             sp.setSuccessful(true);  
    46               
    47             //下面进一步分析服务器端返回的信息,以判断本次交易是否成功  
    48             Iterator<MatchResult> matchResults = matchResponse.getMatchResults().iterator();  
    49             MatchResult matchResult;  
    50             MatchScore score;  
    51             while(matchResults.hasNext()){  
    52                 matchResult = matchResults.next();  
    53                 Iterator<MatchScore> scores = matchResult.getMatchScores().iterator();  
    54                 while(scores.hasNext()){  
    55                     score = scores.next();  
    56                     if (score.score<9999.0){  
    57                         sp.setSuccessful(false);  
    58                         break;  
    59                     }  
    60                 }  
    61             }  
    62         } catch (Exception e) {  
    63             sp.sampleEnd();  
    64             sp.setSuccessful(false);     
    65             e.printStackTrace();  
    66             return sp;     
    67         }  
    68           
    69         return sp;  //返回采用结果,这个结果将会被JMeter使用,并反馈到GUI/报告中,方便明了  
    70 }  


    4. 重载并编写teardownTest方法。

    1 @Override  
    2 public void teardownTest(JavaSamplerContext context) {     
    3     //TODO: clean up      
    4 }  

    天下没有不散的筵席,落幕时分跟JUnit的tearDown一样,但据我测试的效果来看,这玩意全局只调用一次,而非跟setupTest那样每个线程都来一次。

    下面谈谈怎么配置JMeter,并真正跑起来。

    有几个步骤:

    1. 安装JMeter...咳废话

    2. 打包Benchmark为jar并拷贝所有的依赖到 %apache-jmeter%libext下。

    我用maven,就更简单了,配上下面那段:

     1 <plugin>  
     2     <groupId>org.apache.maven.plugins</groupId>  
     3     <artifactId>maven-jar-plugin</artifactId>  
     4     <version>2.3.1</version>  
     5     <configuration>  
     6         <archive>  
     7             <manifest>  
     8                 <addClasspath>true</addClasspath>  
     9                 <classpathPrefix>lib/</classpathPrefix>  
    10             </manifest>  
    11             <manifestEntries>  
    12                 <Class-Path>.</Class-Path>  
    13             </manifestEntries>   
    14         </archive>  
    15     </configuration>  
    16 </plugin>  

    这样拷贝过去的就是:

    %apache-jmeter%libext我的benchmark.jar

    %apache-jmeter%libextlib*——各种杂七杂八的依赖

    3. 启动JMeter。

    双击%apache-jmeter%injmeter.bat

    4. 新增一个Thread Group.

    右键Test Plan->Add->Threads (Users)->Thread Group

    改名为Benchmark,并设置几个重量级的参数:

    a) Number of Threads (users),并发的线程数
    b) Ramp-Up Period (in seconds),预热时间,类似于一般意义上的Think Time
    c) Loop Count,每组并发线程循环的次数

    d) Scheduler是另外一组用来配置调度的,我没用这个

    附上图:

    5. 新增Java Request.

    右键刚新增的线程组(这里名叫Benchmark了)-> Add -> Sampler -> Java Request

    默认情况下,如果你仅放了一个Java Sampler,JMeter即可通过扫他的classpath扫到你的Java Sampler并自动出现在GUI上。如下图:

    6. 再放一到若干个Listener,用以观察输出/图形化报表

    一般而言,我喜欢放两个,一个是最最朴素的"View Results in Table":

    右键刚新增的线程组Benchmark-> Add -> Listener -> View Results in Table

    再来一个"Graph Full Results",图形化的

    到此为止,基本配置完毕,保存一下。

    跑Benchmark其实就很简单了,一般而言三个步骤:

    1. 调整Thread Group的参数,一般包括Number of Threads (users)和Loop Count,以配合不同的压力场景

    2. 调整必要的参数,通过点击Java Request,即可控制你的Java Sampler的每个参数细节

    3. 点击Start,并观察输出,包括View Results in Table或者Graph Full Results。输出主要包括:No of Samples、Latest Sample、Average、Deviation、Throughput、Median等,够用了。如下图:

    附:一般而言,如果线程不是太吓人(比如超过1000),一个JMeter实例就够了,如果多了,就要考虑多个JMeter实例并行测试了。

    ==The End==

  • 相关阅读:
    typro常用快捷键
    02: kali-linux破解密码运行脚本并隐藏进程
    01:kali安装使用
    01: 模拟挖矿黑客攻击过程
    12: docker-compose部署django+nginx+uwsgi+celery+redis+mysql
    11: Django + gunicorn + Nginx 的生产环境部署
    博客说明
    计算机中原码,反码,补码之间的关系
    修改linux下yum镜像源为国内镜像
    webp图片技术调研最终结论(完全真实数据可自行分析)
  • 原文地址:https://www.cnblogs.com/wangxiaoqun/p/7372430.html
Copyright © 2020-2023  润新知