精华帖 (0) :: 良好帖 (2) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-05-06
以前碰到更多的是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即可轻松实现。
public class Benchmark extends AbstractJavaSamplerClient { ... } Benchmark有很多的场景,可以写很多个Benchmark类,比如Benchmark_A, Benchmark_B,我偷懒,四大场景我就写了一个。
好了,下面重点说说需要实现的部分,及其作用。
1. 重载getDefaultParameters方法。 @Override public Arguments getDefaultParameters(){ Arguments params = new Arguments(); //TODO: Right here to define/set parameters from GUI. return params; } 在这个方法里,可以设置各种参数,这些参数可以从GUI处获取,也可以设置合适的默认值。有意思的是,这些默认值在GUI扫描的时候,会自动出现在界面上,以供必要的调整和优化。
2. 重载setupTest方法。 @Override public void setupTest(JavaSamplerContext arg0) { //TODO: to init the test case, something like JUnit's setUp } 为了达到真正的性能测试目的,所有的数据准备工作,应在这里完成。 需要注意的是,这个方法在JMeter初始化的每个线程都会执行一遍,而不是全局仅一遍。
3. 重载并重点编写runTest方法。 @Override public SampleResult runTest(JavaSamplerContext arg0) { //TODO: The load testing client side logic acting as the emulators puts here } 这是我们重点要做编写的客户端代码,为Java Sampler实现的重点。 在这里,你可以尽情的调用客户端的API,完成所需要与服务器端交互的一切,包括交易成功与否的判断。 所谓代码胜千言,下面看看代码好了,加上了注释,就不用废话了: @Override public SampleResult runTest(JavaSamplerContext arg0) { SampleResult sp = new SampleResult(); //采样结果 MatchResponse matchResponse; UUID uuid = UUID.randomUUID(); String key = uuid.toString(); sp.sampleStart(); //采用开始时间 //下面是客户端逻辑 try { if("PC2-ID".equalsIgnoreCase(benchmark_mode)){ matchResponse = client.sendMatchRequest( key, ENGINE.code(), pc2Image, sourcePositions, targetIdentifiers, ImageType.PC2.imageCode()); }else if("WSQ-ID".equalsIgnoreCase(benchmark_mode)){ matchResponse = client.sendMatchRequest( key, ENGINE.code(), wsqImage, sourcePositions, targetIdentifiers, ImageType.WSQ.imageCode()); }else if("ID-ID".equalsIgnoreCase(benchmark_mode)){ matchResponse = client.sendMatchRequest( key, ENGINE.code(), sourceIdentifier, sourcePositions, targetIdentifiers, ImageType.PC2.imageCode()); }else{ print("Not supported benchmark mode found", benchmark_mode); throw new java.lang.IllegalArgumentException("Not supported benchmark mode found"); } sp.sampleEnd(); //采用结束 this.printMatchResponse(matchResponse); //set success flag to true but need to verify later sp.setSuccessful(true); //下面进一步分析服务器端返回的信息,以判断本次交易是否成功 Iterator<MatchResult> matchResults = matchResponse.getMatchResults().iterator(); MatchResult matchResult; MatchScore score; while(matchResults.hasNext()){ matchResult = matchResults.next(); Iterator<MatchScore> scores = matchResult.getMatchScores().iterator(); while(scores.hasNext()){ score = scores.next(); if (score.score<9999.0){ sp.setSuccessful(false); break; } } } } catch (Exception e) { sp.sampleEnd(); sp.setSuccessful(false); e.printStackTrace(); return sp; } return sp; //返回采用结果,这个结果将会被JMeter使用,并反馈到GUI/报告中,方便明了 } 4. 重载并编写teardownTest方法。 @Override public void teardownTest(JavaSamplerContext context) { //TODO: clean up } 天下没有不散的筵席,落幕时分跟JUnit的tearDown一样,但据我测试的效果来看,这玩意全局只调用一次,而非跟setupTest 那样每个线程都来一次。
下面谈谈怎么配置JMeter,并真正跑起来。
有几个步骤: 1. 安装JMeter...咳废话 2. 打包Benchmark为jar并拷贝所有的依赖到 %apache-jmeter%\lib\ext下。 我用maven,就更简单了,配上下面那段: <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.3.1</version> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> </manifest> <manifestEntries> <Class-Path>.</Class-Path> </manifestEntries> </archive> </configuration> </plugin> 这样拷贝过去的就是: %apache-jmeter%\lib\ext\我的benchmark.jar %apache-jmeter%\lib\ext\lib\*——各种杂七杂八的依赖
3. 启动JMeter。 双击%apache-jmeter%\bin\jmeter.bat
4. 新增一个Thread Group. 右键Test Plan->Add->Threads (Users)->Thread Group 改名为Benchmark,并设置几个重量级的参数: a) Number of Threads (users),并发的线程数 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== 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2012-05-07
留下足迹,明天在看。
|
|
返回顶楼 | |
发表时间:2012-05-07
介绍的比较详细。
|
|
返回顶楼 | |
发表时间:2012-05-07
Tomcat911 写道 介绍的比较详细。
蛮好的 |
|
返回顶楼 | |
发表时间:2012-05-08
介绍的不错,相当好
|
|
返回顶楼 | |
发表时间:2012-05-08
谢谢,让我重新了解了 jmeter,以前都是简单的做个访问压力测试!
|
|
返回顶楼 | |
发表时间:2012-05-08
Ozone 写道 谢谢,让我重新了解了 jmeter,以前都是简单的做个访问压力测试!
呵呵,我也有同感,很多东西原来可能存在一定偏见,只有深入了解才知道它的好。 我原来一直也是以为只是个简单的HTTP压力测试小工具,用了才发现其实很强大,基于其接口能做很多高定制性的东西。 |
|
返回顶楼 | |
发表时间:2012-05-08
相比lz说的那些,我一直觉得 jrmc 最好用。
|
|
返回顶楼 | |
发表时间:2012-05-09
javeaye 写道 相比lz说的那些,我一直觉得 jrmc 最好用。 JRMC or BEA JRockit Mission Control? 如果是这个东西的话,我用过,但这个是profiling用的,类似于jprofiler,不一样 不知道楼上这位老兄说的是哪个神器。 |
|
返回顶楼 | |
发表时间:2012-12-14
有个问题请教LZ。
您的引擎用的是Netty + Protobuf,为什么选择扩展AbstractJavaSamplerClient,而不是参考TCPSampler(扩展AbstractSampler)呢? 按理说,TCPSampler更贴近实际环境。除非LZ是测试的侧重点不同。 |
|
返回顶楼 | |
浏览 10455 次