赞
踩
Jmeter提供默认界面(AbstractJavaSamplerClient)和自定义界面的(AbstractSamplerGui)两种自定义取样器的插件开发方式,对于复杂的压测任务,可以通过自定义取样器的方式来实现。
本文通过压测SpringBoot的http接口演示两个自定义扩展类的实现方式:
maven项目工程,pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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>com.penngo.example</groupId> <artifactId>gateway-service</artifactId> <version>1.0.0-SNAPSHOT</version> <name>gateway-service</name> <description>https://blog.csdn.net/penngo</description> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <java.version>11</java.version> <spring-boot.version>2.7.2</spring-boot.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.penngo.example.service.Service2App</mainClass> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
http接口示例代码,Service2App.java
package com.penngo.example.service; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.Map; @SpringBootApplication public class Service2App { public static void main(String[] args) { SpringApplication.run(Service2App.class, args); } @RestController public class HelloController { @GetMapping("/test") public Map test(HttpServletRequest request){ String page = request.getParameter("page"); String keyword = request.getParameter("keyword"); String userid = ""; Cookie[] cookies = request.getCookies(); if (cookies != null) { for(Cookie cookie:cookies){ if(cookie.getName().equals("userid")){ userid = cookie.getValue(); break; } } } Map<String, String> data = new HashMap<>(); data.put("page", page); data.put("keyword", keyword); data.put("userid", userid); return data; } } }
两种扩展的实现代码都在同一个maven工程里面,pom.xml代码:
<?xml version="1.0" encoding="UTF-8"?> <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>com.test.jmeter</groupId> <version>1.0.0</version> <artifactId>jmter_test</artifactId> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.15.2</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.5</version> </dependency> <!-- 注意与Jmeter的版本一致 --> <dependency> <groupId>org.apache.jmeter</groupId> <artifactId>ApacheJMeter_core</artifactId> <version>5.4.3</version> </dependency> <dependency> <groupId>org.apache.jmeter</groupId> <artifactId>ApacheJMeter_java</artifactId> <version>5.4.3</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.17.2</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.17.2</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.36</version> </dependency> </dependencies> </project>
可通过getDefaultParameters()接口,实现在默认界面上配置参数,SampleResult负责记录样本结果,TestHttpSampler.java代码:
package com.test.jmeter; import cn.hutool.json.JSONUtil; 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 org.jsoup.Connection; import org.jsoup.Jsoup; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.HashMap; import java.util.Map; import java.util.Random; public class TestHttpSampler extends AbstractJavaSamplerClient { private static final Logger log = LoggerFactory.getLogger(TestHttpSampler.class); @Override public SampleResult runTest(JavaSamplerContext javaSamplerContext) { String url = javaSamplerContext.getParameter("url"); String userid = javaSamplerContext.getParameter("userid"); Map<String, String> cookieMap = new HashMap(); cookieMap.put("userid", userid); SampleResult sampleResult = new SampleResult(); sampleResult.setSampleLabel("JavaSamplerClient请求查询"); sampleResult.sampleStart(); try { Map<String, String> data = data(); sampleResult.setRequestHeaders(JSONUtil.toJsonStr(data)); var res = Jsoup.connect(url) .header("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8") .ignoreContentType(true) .cookies(cookieMap) .data(data) .method(Connection.Method.GET) .execute(); String body = res.body(); log.info(body); sampleResult.setSuccessful(true); sampleResult.setResponseCode("200"); sampleResult.setResponseData(body, "UTF-8"); sampleResult.setResponseCodeOK(); } catch(Exception e){ log.error("runTest error:",e); sampleResult.setResponseCode("500"); sampleResult.setSuccessful(false); sampleResult.setResponseData("exception," + e.getMessage(), "UTF-8"); } sampleResult.sampleEnd(); return sampleResult; } private Map<String, String> data(){ Random r = new Random(); String page = String.valueOf((r.nextInt(5) + 1)); StringBuffer keyword = new StringBuffer(); String str = "abcdefghijklmnopqrstuvwxyz"; for(int i = 0; i < 7; i++){ keyword.append(str.toCharArray()[r.nextInt(str.length())]); } Map<String, String> data = new HashMap<>(); data.put("page",page); data.put("keyword",keyword.toString()); return data; } public Arguments getDefaultParameters() { Arguments arguments = new Arguments(); arguments.addArgument("url", ""); arguments.addArgument("userid", ""); return arguments; } }
自定义界面的UI库是基于swing,可以使用所有的swing组件
package com.test.jmeter; import org.apache.jmeter.samplers.gui.AbstractSamplerGui; import org.apache.jmeter.testelement.TestElement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.swing.*; import java.awt.*; public class TestGuiHttpSampler extends AbstractSamplerGui { private static final Logger log = LoggerFactory.getLogger(TestGuiHttpSampler.class); private JTextField urlField = null; private JTextField useridField = null; public TestGuiHttpSampler(){ urlField = new JTextField(); useridField = new JTextField(); initUI(); } private void initUI(){ JPanel topPanel = new JPanel(new GridBagLayout()); topPanel.add(new JLabel("http参数"), new GB(0,0,1,1).setInsets(5)); topPanel.add(new JLabel("访问地址:"), new GB(0,1,1,1).setInsets(5)); topPanel.add(urlField, new GB(1,1,1,1).setInsets(5).setFill(GB.BOTH).setWeight(100,0)); topPanel.add(new JPanel(), new GB(0,2,2,1).setInsets(5).setFill(GB.BOTH).setWeight(100,100)); JPanel bottomPanel = new JPanel(new GridBagLayout()); bottomPanel.add(new JLabel("Cookie参数"), new GB(0,0,1,1).setInsets(5)); bottomPanel.add(new JLabel("用户id:"), new GB(0,1,1,1).setInsets(5)); bottomPanel.add(useridField, new GB(1,1,1,1).setInsets(5).setFill(GB.BOTH).setWeight(100,0)); bottomPanel.add(new JPanel(), new GB(0,2,2,1).setInsets(5).setFill(GB.BOTH).setWeight(100,100)); JSplitPane splitPane = new JSplitPane(); splitPane.setOneTouchExpandable(true); splitPane.setContinuousLayout(true); log.info("====TestGuiHttpSampler size:" + this.getSize()); splitPane.setDividerLocation(50); splitPane.setPreferredSize(this.getSize()); splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT); splitPane.setTopComponent(topPanel); splitPane.setBottomComponent(bottomPanel); setLayout(new BorderLayout()); add(splitPane, BorderLayout.CENTER); } @Override public String getLabelResource() { return null; } @Override public TestElement createTestElement() { TestGuiSampler sample = new TestGuiSampler(); return sample; } @Override public void modifyTestElement(TestElement testElement) { testElement.clear(); configureTestElement(testElement); testElement.setProperty(TestGuiSampler.URL, urlField.getText()); testElement.setProperty(TestGuiSampler.USERID, useridField.getText()); } @Override public boolean canBeAdded() { return super.canBeAdded(); } @Override public String getStaticLabel() { return "TestGuiHttpSampler测试"; } @Override public void clearGui() { super.clearGui(); urlField.setText(""); useridField.setText(""); } }
工程项目打包,把jmter_test-1.0.0.jar、jsoup-1.15.2.jar、hutool-all-5.8.5.jar三个包扔到apache-jmeter-5.4.3\lib\ext目录中,重新启动Jmeter。
在线程组上鼠标右键,弹出菜单中选择“取样器->Java请求中”,在面板的下拉框中可以看到实现的扩展类名并选择。


在线程组上右键,在取样器的子菜单中,能看到实现的扩展类"TestGuiHttpSampler测试",选择即可



Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。