目录
1.前言
2.新建一个springboot工程
2.1 引入相关依赖
2.2 编写核心代码
2.2.1 取样器代码
2.2.2 取样器界面
2.2.3 sdk接口封装
3.源码打包
3.1 将sdk源码和采样器源码打成jar包
3.2 拷贝引用包
4.配置jmeter脚本
4.1 选择自定义采样器
4.2 界面里面配置参数
1.前言
当测试的接口响应时间很短时,例如1ms以下,测试如果直接压测spring工程代码,那么spring框架的耗时占比较高,导致实际测试结果的tps误差较大,此时需要自己开发采样器插件,尽可能减少框架对测试结果的影响
2.新建一个springboot工程
2.1 引入相关依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>es.jma</groupId>
<artifactId>jmeter-sampler-test</artifactId>
<version>1.0.0</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</build>
<packaging>jar</packaging>
<name>jmeterSamplerTest</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--jmeter核心包-->
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_core</artifactId>
<version>4.0</version>
</dependency>
<!--需要测试的sdk-->
<dependency>
<groupId>org.example</groupId>
<artifactId>dap-paas-spring-seq-client</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
2.2 编写核心代码
主要有3个类:取样器,取样器界面,sdk接口封装类
2.2.1 取样器代码
package jmeter.sampler;
import org.apache.jmeter.samplers.AbstractSampler;
import org.apache.jmeter.samplers.Entry;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.testelement.TestStateListener;
/**
* @author jy
* MySampler MySampler
*/
public class MySampler extends AbstractSampler implements TestStateListener {
//自定义一个标识
private static final String SEQ_CODE = "sequence.seqCode";
private static final String DATE = "sequence.date";
private static final String HTTPS_REQUEST = "sequence.requests";
@Override
public SampleResult sample(Entry entry) {
SampleResult result = new SampleResult();
result.setSampleLabel("测试采样器");
result.sampleStart();
try {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 10000000; i++) {
stringBuilder.append(i);
}
SequenceGeneratorClientApi sequenceGeneratorClientApi = new SequenceGeneratorClientApi();
String snowFlake = sequenceGeneratorClientApi.getSnowFlake();
result.setResponseCode("200");
result.setResponseMessage(snowFlake);
result.setSuccessful(true);
} catch (Exception e) {
result.setResponseCode("500");
result.setResponseMessage(e.toString());
} finally {
result.sampleEnd();
}
return result;
}
public void setSeqCode(String seqCode) {
setProperty(SEQ_CODE, seqCode);
}
public String getSeqCode() {
return getPropertyAsString(SEQ_CODE);
}
public void setDate(String date) {
setProperty(DATE, date);
}
public String getDate() {
return getPropertyAsString(DATE);
}
public void setHttpsRequest(String requestsString){
setProperty(HTTPS_REQUEST, requestsString);
}
public String getHttpsRequest(){
return getPropertyAsString(HTTPS_REQUEST);
}
@Override
public void testStarted() {
}
@Override
public void testStarted(String s) {
}
@Override
public void testEnded() {
}
@Override
public void testEnded(String s) {
}
}
2.2.2 取样器界面
核心逻辑是配置界面,绑定界面与取样器的参数
package jmeter.sampler;
import org.apache.jmeter.gui.util.JSyntaxTextArea;
import org.apache.jmeter.gui.util.JTextScrollPane;
import org.apache.jmeter.gui.util.VerticalPanel;
import org.apache.jmeter.samplers.gui.AbstractSamplerGui;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jorphan.gui.JLabeledTextField;
import javax.swing.*;
import java.awt.*;
//这个注解必须要有
@SuppressWarnings("deprecation")
public class MySamplerUI extends AbstractSamplerGui {
private final JLabeledTextField seqCode = new JLabeledTextField("序列编码");
private final JLabeledTextField date = new JLabeledTextField("会计日期");
private final JLabeledTextField requestsStringField = new JLabeledTextField("替换符");
private final JSyntaxTextArea textMessage = new JSyntaxTextArea(10, 50);
private final JTextScrollPane textPanel = new JTextScrollPane(textMessage);
public MySamplerUI() {
super();
this.init();
}
private void init() {
setLayout(new BorderLayout());
setBorder(makeBorder());
add(makeTitlePanel(), BorderLayout.NORTH);
JPanel mainPanel = new VerticalPanel();
add(mainPanel, BorderLayout.CENTER);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(4, 2));
panel.add(seqCode);
panel.add(date);
panel.add(requestsStringField);
JPanel controlPanel = new VerticalPanel();
controlPanel.add(panel);
controlPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.gray), "参数"));
mainPanel.add(controlPanel);
//这是是输出
JPanel contentPanel = new VerticalPanel();
JPanel messageContentPanel = new JPanel(new BorderLayout());
messageContentPanel.add(this.textPanel, BorderLayout.CENTER);
contentPanel.add(messageContentPanel);
contentPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.gray), "内容"));
mainPanel.add(contentPanel);
}
/**
* 该方法创建一个新的Sampler,然后将界面中的数据设置到这个新的Sampler实例中。
**/
@Override
public TestElement createTestElement() {
MySampler sampler = new MySampler();
this.setupSamplerProperties(sampler);
return sampler;
}
/**
* 该方法会在reset新界面的时候调用,这里可以填入界面控件中需要显示的一些缺省的值。
**/
@Override
public void clearGui() {
super.clearGui();
this.seqCode.setText("seq");
this.date.setText("2024-09-24");
this.requestsStringField.setText("123456");
}
/**
* 界面与Sampler之间的数据交换
* 该方法用于把Sampler中的数据加载到界面中。
* 在实现自己的逻辑之前,先调用一下父类的方法super.configure(el),这样可以确保框架自动为你加载一些缺省数据,比如Sampler的名字。
**/
@Override
public void configure(TestElement el) {
super.configure(el);
MySampler sampler = (MySampler) el;
this.seqCode.setText(sampler.getSeqCode());
this.date.setText(sampler.getDate());
this.requestsStringField.setText(sampler.getHttpsRequest());
}
private void setupSamplerProperties(MySampler sampler) {
this.configureTestElement(sampler);
sampler.setSeqCode(this.seqCode.getText());
sampler.setDate(this.date.getText());
sampler.setHttpsRequest(this.requestsStringField.getText());
}
/**
* gui显示sample的名称
**/
@Override
public String getStaticLabel() {
return "MySampler";
}
@Override
public String getLabelResource() {
throw new IllegalStateException("This shouldn't be called");
}
/**
* 这个方法用于把界面的数据移到Sampler中,刚好与上面的方法相反。
* 在调用自己的实现方法之前,请先调用一下super.configureTestElement(e),这个会帮助移到一些缺省的数据。
**/
@Override
public void modifyTestElement(TestElement testElement) {
MySampler sampler = (MySampler) testElement;
this.setupSamplerProperties(sampler);
}
}
2.2.3 sdk接口封装
package jmeter.sampler;
import org.example.service.impl.SequenceGeneratorClientImpl;
/**
* @author jy
* SequenceGeneratorClientApi SequenceGeneratorClientApi
*/
public class SequenceGeneratorClientApi {
public static SequenceGeneratorClientImpl sequenceGeneratorClientImpl;
public SequenceGeneratorClientApi() {
sequenceGeneratorClientImpl = new SequenceGeneratorClientImpl();
}
public String getSnowFlake() {
return sequenceGeneratorClientImpl.getSnowFlake();
}
}
3.源码打包
3.1 将sdk源码和采样器源码打成jar包
3.2 拷贝引用包
使用命令“mvn dependency:copy-dependencies -DoutputDirectory=lib”将所有引用的包拷贝到lib目录下
将上面所有的jar包全部拷贝到jmeter的lib\ext文件夹目录下,注意不要覆盖jmeter原有的包,否则jmeter不能正常启动