天天看點

如何內建PTS的JMeter OpenAPI搭建壓測平台1 前言2 依賴3 功能4 使用5 一鍵啟動

1 前言

jmeter是性能壓測領域應用最廣泛開源軟體,提供了非常好的擴充能力,通過社群支援非常多類型的壓測,但是jmeter的分布式壓測、監控等方面的能力還有待提高。而PTS(

Performance Testing Service,性能測試

)能夠提供全國多地域、大規模分布式施壓能力、全面的壓測監控能力、壓測分析能力,彌補了jmeter在性能壓測中的劣勢。是以PTS将jmeter和PTS的能力結合,各取所長,并開放了PTS的JMeter OpenAPI,友善使用者直接通過引入pom的方式編碼調用API。本文主要介紹如何使用 PTS的JMeter OpenAPI搭建一個壓測平台,實作直接使用PTS分布式能力運作jmeter腳本進行壓測。其中包含OpenAPI種類和實作的功能,以及如何使用OpenAPI。并附了一份詳細的使用教程,基本可以實作填空式程式設計。

1.1 場景

pts的jmeter壓測以場景為核心,壓測對象為一個場景,場景中包括jmeter腳本、jmeter依賴、及一些壓測配置,每次壓測會生成一個壓測任務同時生成一個報告。對場景的操作分為兩方面,一是對場景配置的增删改查,二是對場景的壓測和調試。

如何內建PTS的JMeter OpenAPI搭建壓測平台1 前言2 依賴3 功能4 使用5 一鍵啟動

1.2 jmx腳本

即jmeter的原生腳本,可直接在jmeter的GUI頁面中配置導出。

1.3 環境

環境為jmeter壓測的依賴,一個環境包括一系列依賴jar包和一系列properties配置。場景可以綁定某一個環境,以便在壓測過程中引用環境中jar包,而不用每次配置場景都上傳依賴jar包。對環境的操作主要是增删改查。

1.4 其他壓測配置

其他配置主要是PTS壓測的配置,例如公網/VPC壓測、并發量、引擎數量、壓測時長等。

2 依賴

最新版本可以在

maven公網位址

查詢。

<!--建立pts場景需要的實體類,如果隻使用jmeter壓測則不需要引入-->
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>pts-api-entity</artifactId>
            <version>1.0.1</version>
        </dependency>

        <!--PTS Java SDK依賴。-->
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>pts20201020</artifactId>
            <version>1.8.2</version>
            <exclusions>
              <exclusion>
                <groupId>com.aliyun</groupId>
                <artifactId>tea</artifactId>
              </exclusion>
            </exclusions>
        </dependency>
        <dependency>
          <groupId>com.aliyun</groupId>
          <artifactId>tea</artifactId>
            <version>1.1.14</version>
        </dependency>

        <!--阿裡雲核心庫。-->
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>4.5.2</version>
        </dependency>           

3 功能

PTS壓測以場景為中心,借助PTS能力壓測的jmeter也不例外。圍繞jmeter場景,OpenAPI提供了如下幾類功能:編輯場景、調試場景、壓測場景、檢視運作時資料、檢視報告。

如何內建PTS的JMeter OpenAPI搭建壓測平台1 前言2 依賴3 功能4 使用5 一鍵啟動
  • 編輯場景:實作場景的增、删、改、查各種操作。
  • 調試場景:實作場景的壓測前調試。調試過程中可以通過壓測資料接口擷取調試結果資料,判斷待壓測API是否通,若不通過可提前停止調試。
  • 壓測場景:實作場景的啟動、停止。調試成功後,可通過啟動壓測接口,實作一鍵啟動壓測,并在壓測過程中,随時停止壓測。
  • 檢視運作時資料:擷取壓測和調試過程中的實時資料。場景啟動壓測後,pts後端會5s上傳一次資料,這個過程中可以實時看到壓測執行情況,包括采樣器實時采樣的情況、壓測任務所處階段、執行壓測引擎、實時消耗的vum等。
  • 檢視報告:查詢壓測最終報告資料。場景每次壓測都會生成一個壓測任務,同時生成一個壓測任務對應的壓測報告,壓測報告中除了jmeter原生的日志外,還有pts針對某個采樣器的成功率、TPS、RT名額的聚合資料。對報告的操作主要包括檢視報告清單、檢視jmeter原生日志以及pts對jmeter采樣器壓測名額的聚合資料。

4 使用

如何內建PTS的JMeter OpenAPI搭建壓測平台1 前言2 依賴3 功能4 使用5 一鍵啟動
// 使用OpenAPI之前都需要建構一個client
Config config = new Config();
config.setAccessKeyId(accessKeyId);
config.setAccessKeySecret(accessKeySecret);
Client client = new Client(config);           

4.1 編輯場景

建立/修改場景

SaveOpenJMeterSceneRequest request = new SaveOpenJMeterSceneRequest();
// 定義場景
SaveOpenJMeterSceneRequest.SaveOpenJMeterSceneRequestOpenJMeterScene scene = new SaveOpenJMeterSceneRequest.SaveOpenJMeterSceneRequestOpenJMeterScene();
// 設定引擎數量
scene.setAgentCount(2);
// 設定場景名
scene.setSceneName("test");
// 設定檔案清單,包括jmeter腳本、jmeter壓測依賴jar包、配置額度資料檔案等
List<SaveOpenJMeterSceneRequest.SaveOpenJMeterSceneRequestOpenJMeterSceneFileList> fileList = new ArrayList<>();
// 設定檔案的屬性 需要設定檔案的名稱和檔案公網可通路的oss位址
SaveOpenJMeterSceneRequest.SaveOpenJMeterSceneRequestOpenJMeterSceneFileList file = new SaveOpenJMeterSceneRequest.SaveOpenJMeterSceneRequestOpenJMeterSceneFileList();
file.setFileName("json.jar");
file.setFileOssAddress("https://xx.oss-cn-shanghai.aliyuncs.com/json.jar");
fileList.add(file);
SaveOpenJMeterSceneRequest.SaveOpenJMeterSceneRequestOpenJMeterSceneFileList testFile = new SaveOpenJMeterSceneRequest.SaveOpenJMeterSceneRequestOpenJMeterSceneFileList();
testFile.setFileName("baidu.jmx");
testFile.setFileOssAddress("https://xx.oss-cn-shanghai.aliyuncs.com/baidu.jmx");
fileList.add(testFile);
scene.setFileList(fileList);
// 設定場景并發
scene.setConcurrency(1000);
// 設定壓測持續時間
scene.setDuration(600);
// 設定測試檔案的名稱,這個檔案需包括在檔案清單中
scene.setTestFile("baidu.jmx");
// 若依賴了jmeter環境,課設定jmeter環境
scene.setEnviromentId("UKS1LH");

// 建立場景不需要設定id,修改場景需要設定id
scene.setSceneId("6FZQUTH");
request.setOpenJMeterScene(scene);
SaveOpenJMeterSceneResponse response = client.saveOpenJMeterScene(request);           

查詢場景

// 擷取場景詳細資訊
GetOpenJMeterSceneRequest request = new GetOpenJMeterSceneRequest();
request.setSceneId("6FZQUTH");
GetOpenJMeterSceneResponse response = client.getOpenJMeterScene(request);           

删除場景

RemoveOpenJMeterSceneRequest request = new RemoveOpenJMeterSceneRequest();
request.setSceneId("6FZQUTH");
RemoveOpenJMeterSceneResponse response = client.removeOpenJMeterScene(request);           

4.2 調試場景

開始調試

StartDebuggingJMeterSceneRequest request = new StartDebuggingJMeterSceneRequest();
request.setSceneId("6FZQUTH");
StartDebuggingJMeterSceneResponse response = client.startDebuggingJMeterScene(request);           

停止調試

StopDebuggingJMeterSceneRequest request = new StopDebuggingJMeterSceneRequest();
request.setSceneId("6FZQUTH");
StopDebuggingJMeterSceneResponse response = client.stopDebuggingJMeterScene(request);           

4.3 壓測場景

開始壓測

StartTestingJMeterSceneRequest request = new StartTestingJMeterSceneRequest();
request.setSceneId("6FZQUTH");
StartTestingJMeterSceneResponse response = client.startTestingJMeterScene(request);           

停止壓測

StopTestingJMeterSceneRequest request = new StopTestingJMeterSceneRequest();
request.setSceneId("6FZQUTH");
StopTestingJMeterSceneResponse response = client.stopTestingJMeterScene(request);           

4.4 檢視運作時資料

GetJMeterSceneRunningDataRequest request = new GetJMeterSceneRunningDataRequest();
request.setSceneId("6FZQUTH");
GetJMeterSceneRunningDataResponse response = client.getJMeterSceneRunningData(request);           

4.5 檢視報告

報告清單

ListJMeterReportsRequest request = new ListJMeterReportsRequest();
// 分頁設定
request.setPageNumber(1);
request.setPageSize(10);
// 查詢條件設定
request.setSceneId("DYYPZIH");
request.setReportId("FLCAE382");
request.setKeyword("test");
request.setBeginTime(1637485804233L);
request.setEndTime(1637485804300L);
ListJMeterReportsResponse response = client.listJMeterReports(request);           

采樣器聚合資料

GetJMeterSampleMetricsRequest request = new GetJMeterSampleMetricsRequest();
// 設定報告id
request.setReportId("FLCAE382");
// 設定采樣器的索引,為空或者<0時,指派為-1傳回全場景
request.setSamplerId(0);
request.setBeginTime(1637485804233L);
request.setEndTime(1637485804300L);
GetJMeterSampleMetricsResponse response = client.getJMeterSampleMetrics(request);           

采樣器采樣日志

GetJMeterSamplingLogsRequest request = new GetJMeterSamplingLogsRequest();
// 分頁設定
request.setPageNumber(1);
request.setPageSize(10);
// 條件設定
request.setReportId("FLCAE382");
request.setBeginTime(1637224899406L);
request.setEndTime(1637224976000L);
// 關鍵字
request.setKeyword("test");
// 采樣器索引
request.setSamplerId(0);
// 結果是否成功
request.setSuccess(true);
// 線程
request.setThread("main");
// 響應碼
request.setResponseCode("200");
// 最小響應時間
request.setMinRT(0);
// 最大響應時間
request.setMaxRT(1000);
// 壓測引擎編号
request.setAgentId(14201002L);
GetJMeterSamplingLogsResponse response = client.getJMeterSamplingLogs(request);           

壓測機器運作日志

GetJMeterLogsRequest request = new GetJMeterLogsRequest();
// 分頁設定
request.setPageNumber(1);
request.setPageSize(10);
// 查詢的壓測引擎索引
request.setAgentIndex(0);
request.setReportId("FLCAE382");
GetJMeterLogsResponse response = client.getJMeterLogs(request);           

5 一鍵啟動

壓測的核心步驟:建立場景->壓測場景->檢視報告,以下代碼實作了使用SDK一鍵啟動壓測場景,并且在完成壓測後檢視壓測報告。具體步驟如下:

  1. 引入pom依賴
  2. 複制下列代碼
  3. 填寫自己的ak/sk
  4. 點選啟動
import com.aliyun.pts20201020.Client;
import com.aliyun.pts20201020.models.*;
import com.aliyun.teaopenapi.models.Config;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;


public class StartingDemo {

    public static void main(String[] args) throws Exception {
        Client client = getClient();
        // 建立場景
        String sceneId = createScene(client);
        // 啟動場景
        String reportId = startTesting(client, sceneId);
        // 最多等待次數
        int count = 0;
        // 查詢是否已生成報告
        while (!hasReport(client, reportId) && count++ < 20) {
            // 若報告還未生成,則等待(30s)一段時間再查詢
            // 根據壓測時間酌情等待
            Thread.sleep(30 * 1000);
        }
        // 檢視報告
        getJMeterReport(client, reportId);
    }

    private static boolean hasReport(Client client, String reportId) throws Exception {
        ListJMeterReportsRequest request = new ListJMeterReportsRequest();
        // 分頁設定
        request.setPageNumber(1);
        request.setPageSize(1);
        // 查詢條件設定
        request.setReportId(reportId);
        ListJMeterReportsResponse response = client.listJMeterReports(request);
        return response.getBody().getReports().size() > 0;
    }

    private static void getJMeterReport(Client client, String reportId) throws Exception {
        // 檢視機器日志
        GetJMeterLogsResponse getJMeterLogsResponse = getJMeterLogs(client, reportId);
        List<Map<String, ?>> logs = getJMeterLogsResponse.getBody().getLogs();
        // 檢視采樣器聚合資料
        GetJMeterSampleMetricsResponse getJMeterSampleMetrics = getJMeterSampleMetrics(client, reportId);
        List<String> sampleMetricList = getJMeterSampleMetrics.getBody().getSampleMetricList();
        // 檢視采樣日志
        GetJMeterSamplingLogsResponse getJMeterSamplingLogs = getJMeterSamplingLogs(client, reportId);
        List<String> sampleResults = getJMeterSamplingLogs.getBody().getSampleResults();
    }

    private static GetJMeterSamplingLogsResponse getJMeterSamplingLogs(Client client, String reportId) throws Exception {
        GetJMeterSamplingLogsRequest request = new GetJMeterSamplingLogsRequest();
        // 分頁設定
        request.setPageNumber(1);
        request.setPageSize(10);
        // 條件設定
        request.setReportId(reportId);
        GetJMeterSamplingLogsResponse response = client.getJMeterSamplingLogs(request);
        return response;
    }

    private static GetJMeterSampleMetricsResponse getJMeterSampleMetrics(Client client, String reportId) throws Exception {
        GetJMeterSampleMetricsRequest request = new GetJMeterSampleMetricsRequest();
        // 設定報告id
        request.setReportId(reportId);
        GetJMeterSampleMetricsResponse response = client.getJMeterSampleMetrics(request);
        return response;
    }

    private static GetJMeterLogsResponse getJMeterLogs(Client client, String reportId) throws Exception {
        GetJMeterLogsRequest request = new GetJMeterLogsRequest();
        // 分頁設定
        request.setPageNumber(1);
        request.setPageSize(10);
        // 查詢的壓測引擎索引
        request.setReportId(reportId);
        GetJMeterLogsResponse response = client.getJMeterLogs(request);
        return response;
    }

    private static String startTesting(Client client, String sceneId) throws Exception {
        StartTestingJMeterSceneResponse startTestingSceneResponse = startTestingScene(client, sceneId);
        String reportId = startTestingSceneResponse.getBody().getReportId();
        return reportId;
    }

    private static StartTestingJMeterSceneResponse startTestingScene(Client client, String sceneId) throws Exception {
        StartTestingJMeterSceneRequest request = new StartTestingJMeterSceneRequest();
        request.setSceneId(sceneId);
        StartTestingJMeterSceneResponse response = client.startTestingJMeterScene(request);
        return response;
    }

    private static String createScene(Client client) throws Exception {
        SaveOpenJMeterSceneRequest request = new SaveOpenJMeterSceneRequest();
        // 定義場景
        SaveOpenJMeterSceneRequest.SaveOpenJMeterSceneRequestOpenJMeterScene scene = new SaveOpenJMeterSceneRequest.SaveOpenJMeterSceneRequestOpenJMeterScene();
        // 設定場景名
        scene.setSceneName("test");
        // 設定檔案清單,包括jmeter腳本、jmeter壓測依賴jar包、配置額度資料檔案等
        List<SaveOpenJMeterSceneRequest.SaveOpenJMeterSceneRequestOpenJMeterSceneFileList> fileList = new ArrayList<SaveOpenJMeterSceneRequest.SaveOpenJMeterSceneRequestOpenJMeterSceneFileList>();
        // 設定檔案的屬性 需要設定檔案的名稱和檔案公網可通路的oss位址
        SaveOpenJMeterSceneRequest.SaveOpenJMeterSceneRequestOpenJMeterSceneFileList testFile = new SaveOpenJMeterSceneRequest.SaveOpenJMeterSceneRequestOpenJMeterSceneFileList();
        testFile.setFileName("baidu.jmx");
        testFile.setFileOssAddress("https://pts-openapi-test.oss-cn-shanghai.aliyuncs.com/baidu.jmx");
        fileList.add(testFile);
        scene.setFileList(fileList);
        // 設定場景并發
        scene.setConcurrency(1000);
        // 設定引擎數量 說明:一台引擎最多能發500并發,最少1并發是以此處能設定的引擎數為[2,1000],另外引擎數量越多消耗vum越快
        scene.setAgentCount(2);
        // 設定壓測持續時間 60s
        scene.setDuration(60);
        // 設定測試檔案的名稱,這個檔案需包括在檔案清單中
        scene.setTestFile("baidu.jmx");
        request.setOpenJMeterScene(scene);
        SaveOpenJMeterSceneResponse response = client.saveOpenJMeterScene(request);
        return response.getBody().getSceneId();
    }

    private static Client getClient() throws Exception {
        // 填寫自己的AK/SK
        String accessKeyId = "ak";
        String accessKeySecret = "sk";
        Config config = new Config();
        config.setAccessKeyId(accessKeyId);
        config.setAccessKeySecret(accessKeySecret);
        Client client = new Client(config);
        return client;
    }
}