Jmeter stress test practice: custom function of Jmeter secondary development | JD Cloud technical team

1 Introduction

Jmeter is a stress testing tool with a wide range of application scenarios under the Apache Foundation. It has the characteristics of light weight, high scalability, and distribution. Jmeter has supported various functions such as random numbers, counters, timestamps, case conversion, and attribute verification, which are convenient for users. If there are commonly used functional functions that are strongly coupled with the business during use, and if Jmeter does not support them, then it is necessary to develop custom functions separately to achieve specific functions.

This article introduces how to develop Jmeter custom functions to quickly generate JD Zeus order standard signs, and at the same time deeply understand Jmeter's plug-in mechanism and high scalability features.

2 Development preparation

  1. Java basic development
  2. Basic use of Maven
  3. Development dependency version
    JDK 1.8.0 Maven 3.6.3 Jmeter 5.4.3

3 Custom function core implementation

3.1 New project

  • Create a new maven project, the project name here is: JSF_Sampler
  • Because it is an extension based on Jmeter, it needs to rely on the two core packages of Jmeter, which are:
  • ApacheJMeter_core
  • ApacheJMeter_java
  • ApacehJMeter_functions

The core configuration of the pom.xml file is as follows

<groupId>com.jd.jmeter.jsf</groupId>
<artifactId>JSF_Sampler</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <jmeter-version>5.4.3</jmeter-version>
</properties>
<dependencies>
        <dependency>
            <groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_core</artifactId>
            <version>${jmeter-version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_java</artifactId>
            <version>${jmeter-version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_functions</artifactId>
            <version>${jmeter-version}</version>
        </dependency>
    </dependencies>

3.2 Inherit and implement the AbstractFunction class

The implementation class implements the following steps in turn

1) Create a new implementation class and inherit AbstractFunction

  • Note: The package name of the implementation class must contain xxx.functions.xxx, and Jmeter uses the naming rules to implement the loading of the implementation class.

2) Rewrite the following methods, see the code comments below for the purpose of each method

  • execute()
  • setParameters()
  • getReferenceKey()
  • getArgumentDesc()
   /**
     * 京东宙斯 下单标准字段常量
     */
    private static final String APP_KEY = "app_key";
    private static final String APP_SECRET = "app_secret";
    private static final String ACCESS_TOKEN = "access_token";
    private static final String TIMESTAMP = "timestamp";
    private static final String V = "v";
    private static final String METHOD = "method";
    private static final String BUY_PARAM_JSON = "360buy_param_json";
    /**
     * Jmeter中自定义的函数名,在Jmeter的函数助手中可以看到
     */
    private static final String FUNC_NAME = "__GenSignFunction";

    /**
     * 自定义函数的描述,入参,出参,方便使用人员参考使用
     */
    private static final List<String> desc = new ArrayList<>();

    static {
        desc.add("This function is used to generate the JD's JOS sign value");
    }
 /**
     * 此为自定义函数核心实现类,其中,入参SampleResult为上次运行的结果,Sampler为当前的采集器;
     * 返回值为该函数的返回值
     * @param sampleResult
     * @param sampler
     * @return
   * @throws InvalidVariableException
 */
 @Override
    public String execute(SampleResult sampleResult, Sampler sampler) throws InvalidVariableException {
        // 入参处理
        String param = String.valueOf((CompoundVariable)paramValues[0]);
        String signResult = paramHandler(param);

        return signResult;
    }

    /**
     * 按京东宙斯sign加密规则生成标准sign
     * @param param
     * @return
     */
    public String paramHandler(String param){
        Map<String,String> valueMap = new HashMap();
        // 按&符号分割
        String[] paramArray = param.split("&");
        for (int i = 0; i < paramArray.length-1; i++) {
            String key = paramArray[i].split("=")[0];
            String value = paramArray[i].split("=")[1];
            valueMap.put(key,value);
        };
        // 京东宙斯标准sign
        String josGign = EncryptUtil.getSignature(valueMap.get("app_secret")+BUY_PARAM_JSON+valueMap.get("360buy_param_json")
        +ACCESS_TOKEN+valueMap.get("access_token")
        +APP_KEY+valueMap.get("app_key")
        +METHOD+valueMap.get("method")
        +TIMESTAMP+valueMap.get("timestamp")
        +V+valueMap.get("v")
        +valueMap.get("app_secret"));
        return josGign;
    }

/**
* 配置入参,jmeter函数助手入参
*/
    @Override
    public void setParameters(Collection<CompoundVariable> collection) throws InvalidVariableException {
        paramValues = collection.toArray();
    }
/**
* 此方法返回自定义的函数名称
*/
    @Override
    public String getReferenceKey() {
        return FUNC_NAME;
    }
/**
* 此方法返回函数描述信息
*/
    @Override
    public List<String> getArgumentDesc() {
        return desc;
    }

3.3 Final project structure

4 Jmeter loads the extension package

After the above development is completed, package this project. Note that the package here must include dependent packages.

4.1 maven build configuration

<build>
        <finalName>${project.artifactId}</finalName>
        <defaultGoal>install</defaultGoal>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>assemble-all</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

4.2 Project packaging

打包指令如下
mvn package -Dmaven.test.skip=true

4.3 Jmeter load extension package

Place the packaged extension package in Jmeter's ext directory: apache-jmeter-5.4.3/lib/ext/

After starting Jmeter, Jmeter will automatically load the extension package in the ext directory

After opening the Jmeter function assistant, you can see the relevant logs printed in this implementation class

5 Custom function call debugging

5.1 Open the Jmeter function assistant and select a custom function

5.2 JD Zeus Interface Verification

Here, JD Express is used to obtain the prefabricated waybill number interface. After inputting the GET request, click the function [Generate & Copy to clipboard] directly to run the function, and the output parameter returns a 32-digit sign value.

GET请求入参
method=jingdong.etms.waybillcode.get&app_key=349559FAE87E66826499890862E40A44&access_token=c8c2bdc8d1684630bb771a503d5b5a7fkyzh×tamp=2022-01-28 15:10:00&360buy_param_json={"preNum":"1","customerCode":"10K43816","orderType":"0"}&v=2.0&sign=EBB52C6CEDA34703ADE72D4AA4D8F316&app_secret=29959e4cadc14ff4998d4fc26d1e5063

6 Summary

This article uses a custom function to realize the generation of the standard sign of Jingdong Zeus. I hope that through this project, everyone can learn:

  • How to re-develop Jmeter to realize your own unique custom functions.
  • Understand why the official introduction of Jmeter is plug-in and highly scalable.
  • Better understand the internal processing mechanism of Jmeter.

Author: JD Logistics Miao Haochong

Source: JD Cloud Developer Community

Guess you like

Origin blog.csdn.net/jdcdev_/article/details/131512425