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下。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM