性能測試相關分享

性能測試相關
1.爲什麼要做性能測試
.基於網絡的分佈式應用
.用戶數量增加-系統負載
.能夠承受的併發用戶數量
.帶寬-CPU-內存的佔用
.硬盤速度是否跟得上
.系統穩定性-響應時間
2.性能測試概念
-負載測試:Load Testing 用戶數量性能
-壓力測試:Stress Testing 高壓力:系統奔潰,卡死
-容量測試:Volumn Testing 最大支撐數量,響應時間
-吞吐量/吞吐率: IO 對應: -吞吐量/吞吐率: IO 對應
3.性能測試關注點
在這裏插入圖片描述
4 性能測試原理

在這裏插入圖片描述
示例:

  
Jmeter性能測試
Jmeter性能測試
一 Jmeter簡單使用
1、創建一個線程組


添加之後如下所示:


參數解釋:
Number of Threads (users):虛擬用戶數,一個虛擬用戶佔用一個進程或線程,設置多少虛擬用戶數在這裏也就是設置多少個線程數。  
Ramp-Up Period (in seconds):準備時長,設置的虛擬用戶數需要多長時間全部啓動。如果線程數爲10,準備時長爲2,那麼需要2秒鐘啓動10個線程,也就是每秒鐘啓動5個線程。 
Loop Count:循環次數,如果勾選Forever,那麼所有線程會一直髮送請求,一到選擇停止運行腳本。
Delay Thread creation until needed:直到需要時延遲線程的創建。
Scheduler:調度器(配置調度器時,需要勾選循環次數爲永遠) 
Duration (seconds):持續時間
Startup delay:啓動延遲時間

2、創建一個HTTP請求


添加之後如下:
這裏我們用百度做測試,用GET請求去請求百度搜索"testSomething"關鍵字(params需要點擊add添加,關鍵字需要點擊URL Encode)


3、添加察看結果樹


4、點擊運行查看結果
這裏我們可以看到請求是200成功


二 Jmeter性能測試

1、Java腳本代碼編寫
1、從Jmeter的安裝目錄lib/ext中拷貝兩個文件ApacheJMeter_core.jar和ApacheJMeter_java.jar到項目中,然後引入這兩個JAR包。

或者在maven項目的pom.xml文件中添加:
  <dependencies>
    <!--jmeter-->
    <dependency>
      <groupId>org.apache.jmeter</groupId>
      <artifactId>ApacheJMeter_core</artifactId>
      <version>5.0</version>
    </dependency>

    <dependency>
      <groupId>org.apache.jmeter</groupId>
      <artifactId>ApacheJMeter_java</artifactId>
      <version>5.0</version>
    </dependency>
    <!--jmeter-->
  
    ...
    </dependencies>
  
然後用maven install,會自動下載插件

2、創建一個類TestSomething,需要繼承於AbstractJavaSamplerClient,同時需要重寫幾個方法:

package com.fshows.test.performance;

import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
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 java.io.IOException;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

public class TestSomething extends AbstractJavaSamplerClient {

    private String encoding = "utf-8";
    private String url = "https://www.baidu.com/";

    /*
     * 初始化方法,初始化性能測試時的每個線程
     * 實際運行時僅執行一次,在測試方法運行前執行,類似於init方法
     */
    @Override
    public void setupTest(JavaSamplerContext context) {
        super.setupTest(context);
        // 這裏做測試前提條件的準備
    }

    /*
     * 性能測試時的線程運行體
     * 測試執行的循環體,根據線程數和循環次數的不同可執行多次
     */
    @Override
    public SampleResult runTest(JavaSamplerContext javaSamplerContext) {
        SampleResult result = new SampleResult();
        result.setDataType(SampleResult.TEXT);

        // 根據被測接口創建請求,組裝參數


        // 放置請求參數requestDate,可以在Jmeter結果樹的request看到
        result.setSamplerData(requestDate.toString());

        // 定義一個事務,表示這是事務的起始點
        result.sampleStart();

        // 請求接口,拿到返回值response


        //定義一個事務,表示這是事務的結束點
        results.sampleEnd();

        // 解析response
        String responseBody = Objects.requireNonNull(response.body()).string();
        JSONObject jsonObject = JSONObject.parseObject(responseBody);

        if (jsonObject.getBoolean("success")) {
            result.setSuccessful(true);
            result.setResponseMessage(responseBody);
            result.setResponseData(responseBody, encoding);
        } else {
            result.setSuccessful(false);
            result.setResponseData("response content error:" + responseBody, encoding);
        }


        // 某些post請求傳遞json數據的實現,這裏我們用OkHttpClient去發送請求
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)//設置連接超時時間
                .readTimeout(20, TimeUnit.SECONDS)//設置讀取超時時間
                .build();

        // 拼接json參數
        JSONObject jsonObj = new JSONObject();
        jsonObj.put("jsonKey", "jsonValue");
        MediaType JSON = MediaType.parse("application/json; charset=utf-8");
        RequestBody requestJsonBody = RequestBody.create(JSON, jsonObj.toString());

        Request request = new Request.Builder()
                .url(url) // 目標url
                .post(requestJsonBody) // json數據
                .addHeader("headersKey", "headersValue") // 某些請求頭傳遞的數據
                .addHeader("content-type", "application/json")
                .build();
        Call call = okHttpClient.newCall(request);

        result.setSamplerData(request.toString());
        try {
            // 請求獲取response
            Response response = call.execute();
            // 解析response

        } catch (IOException e) {
            result.setResponseData("request to server error:" + e, encoding);
            result.setSuccessful(false);
            return result;
        } catch (Exception e) {
            result.setResponseData("other error:" + e, encoding);
            result.setSuccessful(false);
            return result;
        }
        
        // 最後需return result
        return result;
    }


    // 入口函數
    public static void main(String[] args) {
        JavaSamplerContext arg0 = new JavaSamplerContext(new Arguments());
        TestSomething test = new TestSomething();
        test.setupTest(arg0);
        test.runTest(arg0);
    }
}


2、Jmeter運行
1、首先需要將代碼打包,將得到的jar包放在apache-jmeter-5.0\lib\ext目錄下,然後重啓Jmeter
啓動如果出現內存溢出的異常 java.lang.OutOfMemoryError: Java heap space
在apache-jmeter-5.0\bin目錄下根據系統找到對應的啓動項進行修改



if not defined HEAP (
    rem See the unix startup file for the rationale of the following parameters,
    rem including some tuning recommendations
    set HEAP=-Xms1g -Xmx8g -XX:MaxMetaspaceSize=512m
)

2、這次添加完線程組之後需要添加一個 Java Request


添加之後就可以看到打的jar包內寫的代碼用例


3、對Java Request添加查看響應結果
View Results Tree : 結果樹查看
Aggregate Report:聚合報告


我們在線程組裏模擬100個users - Number of Threads (users),然後運行一個Java Request,查看聚合報告

參數解釋:
Label:每個JMeter的element(例如 Java Request)都有一個Name屬性,這裏顯示的就是Name屬性的值
#Samples:請求數,表示這次測試中一共發出了多少個請求
Average:平均響應時間,默認情況下是單個Request的平均響應時間
Median:中位數,也就是 50% 用戶的響應時間  
90% Line:90% 用戶的響應時間  
Min:最小響應時間  
Max:最大響應時間  
Error%:錯誤率,錯誤請求數/請求總數  
Throughput:吞吐量,默認情況下表示每秒完成的請求數(Request per Second)
KB/Sec:每秒從服務器端接收到的數據量

3、Jmeter併發
1、Jmeter啓動了之後線程就會直接發送測試請求,但是如果要模擬在一瞬間高併發量測試的時候,需要調高線程數量,這很耗測試機器的性能,往往無法支持較大的併發數,無法控制每次測試的瞬間併發量,這時候需要使用synchronized timer阻塞線程,直到指定的線程數量到達後,再一起釋放,可以瞬間產生很大的壓力

添加synchronized timer




參數解釋:
Number of Simulated Users to Group by:每集合夠多少個模擬用戶(線程)後發送一次測試請求;如果設置爲0,等同於設置爲線程租中的線程數;確保設置的值不大於它所在線程組包含的用戶數(線程數),否則會一直集結線程而不發出測試請求,直到超時(如果設置了的話)
Example:Number of Simulated Users to Group by: 100   表示併發量是100,也就是說,Jmeter會等到100個線程都運行到此處時,這100個線程纔開始執行後面的操作,先到達的線程將會在此等候

Timeout in milliseconds:超時時間,即多少毫秒後同時釋放已集結的的線程,發送測試請求;如果設置爲0,Timer將等待線程數達到了"Number of Simultaneous Users to Group"中設置的值才釋放
Example:Timeout in milliseconds: 100  表示超時時間爲100ms,當100ms後還沒達到"Number of Simultaneous Users to Group"中設置的值,Timer將不再等待,直接釋放已到達的線程

當我們要進行併發測試時,比如要進行500的併發量測試,需要進行的設置如下:




這樣Jmeter就會集結500個線程(users),集結完成後會在0s內發送完請求,達到併發效果

2、synchronized timer放置位置說明
如果希望定時器僅應用於其中一個sampler,則把該定時器作爲子節點加入,如下圖


如果希望synchronizing timer應用於多個sampler,如下圖,當執行一個sampler之前時,和sampler處於相同作用域的定時器都會被執行


注意:
在Jmeter中,timer是在sampler之前執行的。不管這個定時器的位置放在sampler之後,還是之前。當然,如果有多個timer的時候,在相同作用域下,會按上下順序執行timer,這個就需要慎重放置timer的順序;不過,爲了更好的可讀性,還是建議將timer放在對應的sampler前面或子節點中

4、Jmeter分佈式
待補充

三 相關下載

1、Jmeter
Jmeter下載:http://jmeter.apache.org/download_jmeter.cgi
apache-jmeter-5.0.zip(54.3 MB)

2、插件
此外,Jmeter還提供了插件來滿足不同情況下的需求
插件下載:https://jmeter-plugins.org/install/Install/

如果不想看,可闊以,把下面這個東東放到lib/ext目錄,然後重啓JMeter,在options下選擇自己需要的安裝
https://jmeter-plugins.org/get/  < 就這個


可能,大概,也許會用到的插件:
 jp@gc - Active Threads Over Time -- 活躍線程數量隨時間的推移變化
 jp@gc Transaction per Second -- 每秒事務處理量
 jp@gc Response Times Over Time -- 響應時間隨着時間的推移變化
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章