JMeter使用jar進行壓力測試

weixin_34377065發表於2014-03-25

最近需要對改造的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下。

 

相關文章