JMeter使用jar进行压力测试

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

JMeter介绍

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

Java请求测试(界面操作)

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

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

2)配置JMeter环境变量,增加变量JMETER_HOME,值为“D:\soft\jmeter\apache-jmeter-3.2”,修改变量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界面说明安装成功。

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

ClientJmeter.java

package org.pos.gateway.client;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;

import org.apache.commons.lang3.StringUtils;
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.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LogLevel;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

import com.fft.common.entity.DecodeType;
import com.fft.common.entity.HeartbeatReq;

public class ClientJmeter extends AbstractJavaSamplerClient {

    private IoSession session;

    private long start = 0;//记录测试开始时间;
    private long end = 0;//记录测试结束时间;
    private String ip;
    private String port = "32888"; 
    
    private static String label = "heartbeat";
    
    HeartbeatReq req;
    // 测试结果  
    private SampleResult sr;  

    //初始化操作
    @Override
    public void setupTest(JavaSamplerContext arg0) {
        NioSocketConnector connector = new NioSocketConnector();
        LoggingFilter loggingFilter = new LoggingFilter();
        loggingFilter.setSessionCreatedLogLevel(LogLevel.NONE);// 一个新的session被创建时触发
        loggingFilter.setSessionOpenedLogLevel(LogLevel.NONE);// 一个新的session打开时触发
        loggingFilter.setSessionClosedLogLevel(LogLevel.NONE);// 一个session被关闭时触发
        loggingFilter.setMessageReceivedLogLevel(LogLevel.NONE);// 接收到数据时触发
        loggingFilter.setMessageSentLogLevel(LogLevel.INFO);// 数据被发送后触发
        loggingFilter.setSessionIdleLogLevel(LogLevel.INFO);// 一个session空闲了一定时间后触发
        loggingFilter.setExceptionCaughtLogLevel(LogLevel.NONE);// 当有异常抛出时触发
        connector.getFilterChain().addLast("logger", loggingFilter);
        connector.setConnectTimeoutMillis(30000);
        connector.getFilterChain().addLast("codec",
                new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"),
                        LineDelimiter.WINDOWS.getValue(), 
                        LineDelimiter.WINDOWS.getValue())));
        connector.setHandler(new ClientHandler());
        
        
        // 连接服务器,知道端口、地址
        // ConnectFuture cf = connector.connect(new
        // InetSocketAddress("localhost", 8317));
        ip = arg0.getParameter("ip");    
        port = arg0.getParameter("port");  
        if(StringUtils.isEmpty(ip)) {
            ip = "119.23.213.153";  
        }
        if(StringUtils.isEmpty(port)) {
            port = "32888";  
        }
        System.out.println("====server info: ip=" + ip + ", port=" + port);
        ConnectFuture cf = connector.connect(new InetSocketAddress(ip, Integer.parseInt(port)));
        // 等待连接创建完成
        cf.awaitUninterruptibly();
        System.out.println("test客户端连接服务器成功");
        
        session = cf.getSession();
        
        req = new HeartbeatReq();
        req.setVersion("00");
        req.setTransType(DecodeType.Heartbeat_REQ.getType());
        req.setTransSeq("0");
        req.setReqOrgCode("1234564");
        req.setReqCode("00");
    }
    @Override
    public Arguments getDefaultParameters() {
        Arguments arguments = new Arguments();
        arguments.addArgument("ip", ip);
        arguments.addArgument("port", port);
        return arguments;
    }


    public SampleResult runTest(JavaSamplerContext arg0) {
        sr = new SampleResult();    
        sr.setSampleLabel(label);    
        try{    
            sr.sampleStart(); //记录程序执行时间,以及执行结果    
            //发送数据    
            session.write(req);  
            sr.setSuccessful(true);    
        }catch(Throwable e){    
            sr.setSuccessful(false);    
        }finally{    
            sr.sampleEnd();    
        }    
        return sr;   
    }

    /**
     * 获取jmeter输入的参数值
     *
     * @return
     */
    public void setValues(JavaSamplerContext arg0) {
        ip = arg0.getParameter("ip", ip);
        port = arg0.getParameter("port", port);
    }


    @Override
    public void teardownTest(JavaSamplerContext context) {
        end = System.currentTimeMillis();
        getLogger().info("cost time: " + (end - start) + "ms");
    }
}

ClientHandler.java

package org.pos.gateway.client;

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;


public class ClientHandler extends IoHandlerAdapter {
     public void sessionOpened(IoSession session) throws Exception {
            System.out.println("测试端--会话打开");  
        }  
          
        @Override  
        public void messageReceived(IoSession session, Object message)  
                throws Exception {  
            System.out.println("客户端收到服务端的包内容:" + message);
            System.out.println("客户端收到服务端的应答码:" + ((String)message).substring(142,144));
            System.out.println();
        }  
          
        @Override  
        public void sessionClosed(IoSession session) throws Exception {  
            System.out.println("会话关闭");  
            System.exit(0);
        }  
        @Override  
        public void exceptionCaught(IoSession session, Throwable cause)  
                throws Exception {  
            System.out.println("会话异常");  
            super.exceptionCaught(session, cause);  
        }  
        @Override  
        public void messageSent(IoSession iosession, Object obj) throws Exception {  
            System.out.println("客户端消息发送:" + obj);  
            super.messageSent(iosession, obj);  
        }  
        @Override  
        public void sessionCreated(IoSession iosession) throws Exception {  
            System.out.println("会话创建");  
            super.sessionCreated(iosession);  
        }  
        @Override  
        public void sessionIdle(IoSession iosession, IdleStatus idlestatus)  
                throws Exception {  
            System.out.println("会话休眠");  
            super.sessionIdle(iosession, idlestatus);  
        } 
}

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

 

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

 

问题记录:

1、Jmeter throwing error class org.bouncycastle.asn1.ASN1Primitive overrides final method equals

是导出的jar包与jmeter的jar冲突导致。

解决办法是:将第三方jar分开打包,将所有第三方jar拷贝到lib下,测试工程jar拷贝到lib/ext下。

 

posted on 2014-03-25 16:02  duanxz  阅读(5317)  评论(2编辑  收藏  举报