最近需要对改造的redis缓存接口做压力测试,使用了开源压力测试工具JMeter,分享一下自己的使用经验,希望能对需要进行压力测试的开发同学有所帮助。

JMeter介绍

JMeter是Apache软件基金会下的一款开源压力测试工具,官方网址是:http://jmeter.apache.org/。JMeter可以测试静态、动态资源的性能,这些资源包括文件、Servlets 、Perl脚本、Java对象、数据库、FTP服务器等,并生成图形报告。JMeter使用Java开发,既支持可视化界面操作,也支持命令行操作。

Java请求测试(界面操作)

由于需要对改造的redis缓存接口测试,因此使用了JMeter的Java请求测试,安装和使用步骤如下所示(以Windows操作系统为例,并默认已安装、配置Java运行环境)。

1)从官网上下载JMeter并解压,例如解压至C:\apache-jmeter-2.9。

2)配置JMeter环境变量,增加变量JMETER_HOME,值为“C:\apache-jmeter-2.9”,修改变量CLASSPATH,增加“%JMETER_HOME%\lib\ext\ApacheJMeter_core.jar;% JMETER_HOME%\lib\jorphan.jar;%JMETER_HOME%\lib\logkit-1.2.jar;”


3)执行JMeter目录下的bin\jmeter.bat,显示JMeter界面说明安装成功。

开源压力测试工具JMeter使用介绍_第1张图片

4)新建Java工程,在该工程中,引入JMeter目录下lib中的jar包,继承JMeter的AbstractJavaSamplerClient类,在子类中重写setupTest、teardownTest、getDefaultParameters、runTest方法,实现对缓存接口的get、set、hGet、hSet方法进行测试,子类代码如下所示。

package com.sohu.cms.test;
import org.apache.jmeter.config.Arguments; 
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient; 
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext; 
import org.apache.jmeter.samplers.SampleResult; 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.sohu.cms.datacache.DataCache;
import com.sohu.cms.datacache.DataCacheManager;
/**
 * 继承jmeter的AbstractJavaSamplerClient类,
 * 重写setupTest、teardownTest、getDefaultParameters、runTest方法
 * 对缓存接口的get、set、hGet、hSet方法进行测试
 * @author wang
 *
 */
public class TestDataCacheClient extends AbstractJavaSamplerClient{
    private static long start = 0; 
    private static long end = 0; 
                                                             
    private static DataCacheManager dataCacheManager;
    private static DataCache dataCache;
    private static int size = 8192;
    private static String method = "get";
    private static Object key = "TEST_KEY";
    private static Object field = "TEST_FIELD";
    private static Object value = new Byte[size];
                                                             
    //此处初始化我们改造的redis缓存接口dataCache
    static {
        ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
        dataCacheManager = (DataCacheManager) context.getBean("dataCacheManager");
        dataCache = dataCacheManager.getObjectDataCache(); 
    }
    /**
     * 测试开始
     */ 
    public void setupTest(JavaSamplerContext arg0) {       
        start = System.currentTimeMillis(); 
    } 
    /**
     * 测试结束
     */ 
    public void teardownTest(JavaSamplerContext arg0) {
        end = System.currentTimeMillis(); 
        System.out.println("[method=" + method + "] [size=" + size + "] [time:" + (end - start) / 1000); 
    } 
    /**
     * 添加参数默认值,参数默认值会在界面中显示
     */
    public Arguments getDefaultParameters() {
        //添加两个参数,
        //size为测试value值的字节大小,默认为8192字节
        //method为需要进行测试的缓存接口方法,默认为get
        Arguments args = new Arguments();
        args.addArgument("size", "8192");
        args.addArgument("method","get");
        return args; 
    } 
    /**
     * 测试
     */ 
    public SampleResult runTest(JavaSamplerContext arg0) {
        //获取界面或测试计划配置文件(jmx)中传入的参数
        if (arg0.getParameter("method") != null) method = arg0.getParameter("method");
        if (arg0.getIntParameter("size") > 0) size = arg0.getIntParameter("size");
        value = new Byte[size];
                                                                 
        SampleResult sr = new SampleResult(); 
        try {
            boolean result = true;
            //根据传入的method参数测试相应的缓存接口方法
            if (method.equals("get")){
                //测试用例的核心逻辑
                //测试用例开始
                sr.sampleStart();
                //测试用例执行
                result = get();
                //测试用例结果
                sr.setSuccessful(result);
                //测试用例结束
                sr.sampleEnd();
            } else if (method.equals("set")) {
                sr.sampleStart();
                result = set();
                sr.setSuccessful(result);
                sr.sampleEnd();
            } else if (method.equals("hGet")) {
                sr.sampleStart();
                result = hGet();
                sr.setSuccessful(result);
                sr.sampleEnd();
            } else if (method.equals("hSet")) {
                sr.sampleStart();
                result = hSet();
                sr.setSuccessful(result);
                sr.sampleEnd();
            }
        } catch (Exception e) { 
             e.printStackTrace(); 
        } 
        return sr; 
    }
                                                             
    /**
     * 缓存接口get方法测试用例
     * @return
     */
    public boolean get() {
        boolean result = true;
        try {
            dataCache.get(key);
        } catch (Exception e) {
            System.out.println(e);
            result = false;
        }
        return result;
    }
                                                             
    /**
     * 缓存接口set方法测试用例
     * @return
     */
    public boolean set() {
        boolean result = true;
        try {
            dataCache.put(key, value);
        } catch (Exception e) {
            System.out.println(e);
            result = false;
        }
        return result;
    }
                                                             
    /**
     * 缓存接口hGet方法测试用例
     * @return
     */
    public boolean hGet() {
        boolean result = true;
        try {
            dataCache.hGet(key, field);
        } catch (Exception e) {
            System.out.println(e);
            result = false;
        }
        return result;
    }
                                                             
    /**
     * 缓存接口hSet方法测试用例
     * @return
     */
    public boolean hSet() {
        boolean result = true;
        try {
            result = dataCache.hSet(key, field, value);
        } catch (Exception e) {
            System.out.println(e);
            result = false;
        }
        return result;
    }
}

5)将工程以jar包形式导出,置于JMeter目录lib\ext下,并将工程依赖的jar包置于JMeter目录lib下,启动JMeter。右键“测试计划”添加“线程组”。右键“线程组”添加“Java请求”,右键“Java请求”添加“聚合报告”。

开源压力测试工具JMeter使用介绍_第2张图片

开源压力测试工具JMeter使用介绍_第3张图片

开源压力测试工具JMeter使用介绍_第4张图片

6)在“Java请求”中选择所写的测试类,并可以设置相关参数,在“线程组”中可以设置并发线程数和循环次数,点击上方“启动”按钮开始测试,测试完成后,可以在“聚合报告”中查看到测试结果。

开源压力测试工具JMeter使用介绍_第5张图片

开源压力测试工具JMeter使用介绍_第6张图片

Java请求测试(命令行操作)

JMeter也支持命令行操作,在服务器上进行测试时,我们就采用了这种方式。一个简单的JMeter命令行操作如下所示(在JMeter目录bin下执行)。

Windows下: JMeter-n –t test.jmx -l result.jtl

Linux下: ./jmeter.sh -n –t test.jmx -l result.jtl

其中-n 表示命令行执行,test.jmx为测试计划配置文件,result.jtl为测试结果。

可在界面中进行测试计划配置,然后保存便可生成jmx格式文件,如下所示。



  
    
      
      false
      false
      
        
      
      
    
    
      
        continue
        
          false
          
          100
        
        
        100
        100
        1376103961000
        1376103961000
        false
        
        
      
      
        
          
            
            
              
                size
                8192
                =
              
              
                method
                set
                =
              
            
          
          com.sohu.cms.test.TestDataCacheClient
        
        
          
            false
            
              saveConfig
              
                
                true
                true
                true
                
                true
                true
                true
                true
                false
                true
                true
                false
                false
                false
                false
                false
                false
                false
                false
                0
                true
              
            
            
          
          
        
      
    
  

result.ftl为按行输出的测试执行结果,如下所示,可在界面操作的聚合报告导入该文件从而生成聚合报告。

...

1376040889436,48,Java请求,,,线程组1-40,,true,0,0

1376040889792,9,Java请求,,,线程组1-7,,true,0,0

1376040889526,167,Java请求,,,线程组1-57,,true,0,0

1376040889791,10,Java请求,,,线程组 1-54,,true,0,0

...