使用JMeter進行性能測試 —“Java請求”方式


JMeter是Apache組織的開放源代碼項目,它是功能和性能測試的工具,100%的用java實現,最新的版本是2.9,大家可以到官網下載源代碼和查看相關文檔。之前本科的時候,SQA課程作業中我們組使用過2.4版本,這次更新了2.9感覺最直觀的就是界面上有了小的更改,增加了清除、啟動等按鈕。

關於使用JMeter進行JDBC數據庫測試、HTTP請求接口測試、結合Badboy錄制功能進行網站性能測試等內容,網上的資料比較豐富,這里就暫時不做介紹了。更實用和靈活的場景,是實用我們自己編寫的jar包進行測試,這也就是“Java請求”方式的測試。這里主要記錄一下我在學習這種測試方式時遇到的一些問題,和總體流程,算作一個記錄和小總結。

1. JMeter安裝

 

准確的來說,我認為JMeter是不需要安裝的,下載好JMeter Binary版本后,在本地解壓縮,進入bin文件夾,執行ApacheJMeter.jar文件即可。這里提供一個觀望的2.9版本的下載鏈接,時間久了可能會失效,這個時候可以進入Apache JMeter項目主頁再選擇download頁面。

 

打開JMeter程序后,我們可以看到JMeter的主界面,是下圖的這個樣子(2.9版本)。

 

2. 使用JMeter創建測試計划

如果我們希望實用JMeter進行性能測試,則首先需要創建一個測試計划,我們可以對測試計划進行保存,這樣當我們下一次需要再次執行這個測試的時候,只需要打開已保存的測試計划文件(.jmx文件)就可以執行了,無需再次創建。

1)點擊“測試計划”,在右側輸入框中可以修改測試計划的名稱,並添加注釋,這里我偷個懶就不改了,使用默認的。

2)為測試計划添加一組Threads,選擇線程組。這組Threads就相當於是一組用戶,每個顯示代表一個用戶執行相關操作。

3) 編輯線程組屬性。設置響應內容,比較重要的是線程數、ramp-up period和循環次數。這里設置線程數為1、ramp-up period為1和循環次數1,即線程組中只有1個線程,這個線程在計划啟動后1秒就開始執行,只執行1次。

 

圖上的ramp-up period解釋不正確,這個屬性表示每個用戶(線程)啟動的遲延時間。例如,如果你輸入Ramp-Up Period 為5秒,JMeter將會在五秒結束前完成啟動所有的用戶。所以,如果你有五個用戶並且Ramp-Up Period為5秒,那么開始用戶的延遲就是1秒。(5個用戶/5秒=1用戶每秒)。如果你設置的Ramp-Up Period為0,則JMeter將會立即啟動你所有的用戶。

如果勾選了“調度器”,則可以定時啟動線程。

4)為線程組添加Sampler取樣器,取樣器表明這組線程執行測試的類型,即發送請求的類型、怎樣發送請求的。我們這里選擇“Java請求”,表明這組線程是通過某個Java類發送請求的。

4)編輯“Java請求”屬性。下圖這個大家可以發現已經有了Launcher類,和userName、password、authUrl的值了,這是因為:1. 我之前寫了滿足一定要求的代碼,打了jar包,放入了JMeter的lib/ext文件夾下了,所以可以看到Launcher;2. 我在Launcher類中的getDefaultParameters方法中添加了默認的userName、password、authUrl值。這里的“滿足一定要求”請繼續參閱下文。

5)為Java請求添加監聽器,選擇“聚合報表”和“圖形結果”,這樣在啟動測試后,我們就可以獲得測試結果的數據,分別以報表和圖形的結果展示。

6)點擊啟動(菜單欄中的綠色三角形按鈕)。測試完成可以看到測試結果。為了結果好看一點,我把線程數改成了10,循環改成了100 :P

這里對測試結果中的幾個指標進行說明:

圖形結果
樣本數目 總共發送到服務器的請求數。
最新樣本 代表時間的數字,是服務器響應最后一個請求的時間。
吞吐量 服務器每分鍾處理的請求數。
平均值 是總運行時間除以發送到服務器的請求數,即每個請求的平均響應時間。
中間值 是代表時間的數字,有一半的服務器響應時間低於該值而另一半高於該值。
偏離 表示服務器響應時間變化、離散程度測量值的大小,即數據的分布。

 

 

 

   

 

 

 

 

 

聚合報表
90%line 90%的響應時間都比這個時間小
Min 代表時間的數字,是服務器響應的最短時間。
Max 代表時間的數字,是服務器響應的最長時間。
Error% 請求的錯誤百分比。
KB/sec 是每秒鍾請求的字節數。

 

 

 

 

 

 

 

3. 實現“Java請求”代碼

針對"Java請求"類型的測試,需要基於JMeter測試框架編寫測試用例。

1)新建一個普通的Java工程

2)添加JMeter的包引用,這些包位於 JMeter安裝目錄/lib/ext下,一般只需要ApacheJMeter_core.jar和ApacheJMeter_java.jar這兩個。

3)新建一個Java Class,如下例中的“Launcher”,並繼承“AbstractJavaSamplerClient”。AbstractJavaSamplerClient中默認實現了四個可以覆蓋的方法,分別是“getDefaultParameters”,“setupTest”,“runTest”和“teardownTest”方法。

  • getDefaultParameters 方法主要用於設置傳入界面的參數;
  • setupTest方法為初始化方法,用於初始化性能測試時的每個線程;
  • runTest方法為性能測試時的線程運行體;
  • teardownTest方法為測試結束方法,用於結束性能測試中的每個線程。
package cn.edu.zju.swift.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 cn.edu.zju.swift.JtangSwiftClient;
import cn.edu.zju.swift.model.result.AccountResult;

public class Launcher extends AbstractJavaSamplerClient{
    
    private JtangSwiftClient client;
    
    @Override
    /**
     * JMeter界面中展示出此方法所設置的默認參數。
     * @return
     */
    public Arguments getDefaultParameters() {
        
        Arguments args = new Arguments();
        
        args.addArgument("authUrl", "http://192.168.3.51:8080/auth/v1.0");
        args.addArgument("userName", "test:tester");
        args.addArgument("password", "testing");
                
        return args;
    }

    /** 
     * 執行runTest()方法前會調用此方法,可放一些初始化代碼 
     */ 
    @Override
    public void setupTest(JavaSamplerContext context) {
        
        // 創建SwiftClient
        this.client = new JtangSwiftClient(15000, 15000, 8192, true, false);
    }

    /** 
     * 執行runTest()方法后會調用此方法,可放一些資源釋放代碼
     */ 
    @Override
    public void teardownTest(JavaSamplerContext context) {
        
        // 關閉連接
        this.client.close();
    }

    @Override
    /**
     * 性能測試時的線程運行體,執行的業務方法放在這里。
     */
    public SampleResult runTest(JavaSamplerContext context) {
        
        // 創建SampleResult對象,用於記錄執行結果的狀態,並返回
        SampleResult sampleResult = new SampleResult();

        
        // 獲取JMeter中輸入的用戶參數
        String authUrl = context.getParameter("authUrl");
        String userName = context.getParameter("userName");
        String password = context.getParameter("password");
        
        // 開始
        sampleResult.sampleStart();
        
        AccountResult accountResult = client.auth(authUrl, userName, password);

        // 暫停
        // sampleResult.samplePause();
        
        // 重啟
        // sampleResult.sampleResume();
        
        // 結束
        sampleResult.sampleEnd();
        
        sampleResult.setSuccessful(accountResult.isSuccess());
        
        // 返回
        return sampleResult;
    }
}

4)代碼編寫完畢后,把上面的例子打包(使用eclipse右鍵項目 -> export -> jar,即可)。然后把生成的"swift-random-action-test.jar"文件拷貝到JMeter的安裝目錄lib\ext下,就可以在上述“2. 使用JMeter創建測試計划”的4)Java請求編輯頁面的下拉列表中看到Launcher類了。

這里有兩點需要注意

1. 如果你的jar依賴了其他第三方jar,需要將其一起放到lib/ext下,否則會出現ClassNotFound錯誤,這個問題也是困擾了我好久的 T^T;

2. 如果在將jar放入lib/ext后,你還是無法找到你編寫的類,且此時你是開着JMeter的,則需要重啟一下JMeter。

 

 

以上就是使用JMeter的Java請求方式進行一個測試計划構建的全過程了,都是比較基礎的方法,如果需要什么額外的功能還可以慢慢學習。雖然自己也有寫多線程並發的客戶端測試代碼,並自己收集response time等,計算TPS,但顯然使用JMeter的方式更加方便,因為你只需要按照單線程的方式去實現你的測試業務,也無需添加各種埋點收集數據。

綜上,感覺JMeter還是很強大的,最近打算多學習一點,對以后寫代碼,自我測試性能也是很有幫助的,再配合jProfiler的使用,可以很好的保證Java代碼的效率和性能。當然,工具只能“錦上添花”,最根本的還是需要我們自己可以編寫出高質量的代碼啦 :D

 

 


免責聲明!

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



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