目录
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";@Overridepublic 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);}@Overridepublic void testStarted() {}@Overridepublic void testStarted(String s) {}@Overridepublic void testEnded() {}@Overridepublic 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实例中。**/@Overridepublic TestElement createTestElement() {MySampler sampler = new MySampler();this.setupSamplerProperties(sampler);return sampler;}/*** 该方法会在reset新界面的时候调用,这里可以填入界面控件中需要显示的一些缺省的值。**/@Overridepublic void clearGui() {super.clearGui();this.seqCode.setText("seq");this.date.setText("2024-09-24");this.requestsStringField.setText("123456");}/*** 界面与Sampler之间的数据交换* 该方法用于把Sampler中的数据加载到界面中。* 在实现自己的逻辑之前,先调用一下父类的方法super.configure(el),这样可以确保框架自动为你加载一些缺省数据,比如Sampler的名字。**/@Overridepublic 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的名称**/@Overridepublic String getStaticLabel() {return "MySampler";}@Overridepublic String getLabelResource() {throw new IllegalStateException("This shouldn't be called");}/*** 这个方法用于把界面的数据移到Sampler中,刚好与上面的方法相反。* 在调用自己的实现方法之前,请先调用一下super.configureTestElement(e),这个会帮助移到一些缺省的数据。**/@Overridepublic 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不能正常启动