文章目录
-
- 背景
- 前置条件
- 页面设计
- 运行效果
- 参考代码
-
- 前端代码
- 服务端接口
- interface层代码
- 接口实现层
- 工具类
- jmeter脚本
- 小结
背景 Jmeter 平时性能测试工作一般都是通过命令行在 Linux 下执行,为了锻炼自己代码与逻辑能力,想 Jmeter 是否可以通过 springboot 工程启动,周末在家尝试写一写,一写原来需要处理很多事情,才可以启动起来,起来还是有很问题需要处理,下面是相应的代码,其实网上也有,但关键的是自己有意识收集知识,到用的时候能拿来改一改就用。
前置条件 需要在 linux 中配置 Jmeter,并且配置 Java 环境变量:
## 编辑
vi ~/.bash_profile# jmeter:路径根据自己事情情况修改
JMETER_HOME=/root/tools/apache-jmeter-5.1.1
PATH=$PATH:$HOME/bin:$JMETER_HOME/bin:
export PATH## 执行生效
source ~/.bash_profile
页面设计
文章图片
运行效果 点击上传脚本,弹出对话框,点击上传,后台日志显示上传成功。
【性能|性能工具之 Jmeter 通过 SpringBoot 工程启动】
文章图片
点击启动,并且读取启动日志。
文章图片
点击停止。
文章图片
示意图说明:
通过访问 -> 调用 JAVA 代码-> 启动 shell命令-> 启动 Jmeter -> 获取启动日志
文章图片
参考代码 前端代码
以下参考代码:
Jmeter启动 - 锐客网 >
.bd-placeholder-img {
font-size: 1.125rem;
text-anchor: middle;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}@media (min-width: 768px) {
.bd-placeholder-img-lg {
font-size: 3.5rem;
}
}
文章图片
The Apache JMeter? application is open source software, a 100% pure Java application designed to
load test functional behavior and measure performance. It was originally designed for testing Web
Applications but has since expanded to other test functions.
上传脚本
运行
服务端接口
参考代码如下:
package com.sevendays.controller;
import com.sevendays.pojo.Msg;
import com.sevendays.service.JmerterScriptService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
/**
* @author 7d
* @Title: JmeterController
* @Description: Jmeter启动页面
* @date 2019/11/17 / 10:32
*/@Controller
@RequestMapping("/jmeter")
public class JmeterController {
private static final Logger logger = LoggerFactory.getLogger(JmeterController.class);
@Autowired
JmerterScriptService jmerterScriptService;
@GetMapping("/jmeterIndex")
public String jmeterIndex() {
return "jmeter/jmterIndex";
}/**
* 上传脚本
*
* @param file
* @return
*/
@PostMapping("/upload")
@ResponseBody
public Msg upload(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return Msg.fail().add("err", "上传失败");
}
String fileName = file.getOriginalFilename();
logger.info("路径" + fileName);
String filePath = "/home/7d/";
//String filePath = "E:\\test\\7d\\data\\";
if (!fileName.endsWith(".jmx")) {
return Msg.fail().add("err", "脚本上传失败");
}
File dest = new File(filePath + fileName);
String jmxName = fileName.substring(0, fileName.lastIndexOf("."));
try {
file.transferTo(dest);
logger.info("上传成功:" + jmxName);
return Msg.success().add("file", jmxName);
} catch (IOException e) {
logger.error(e.toString(), e);
}
return Msg.fail();
}/**
* 上传参数文件
*
* @param file
* @return
*/
@PostMapping("/Paramupload")
@ResponseBody
public Msg uploadParam(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return Msg.fail().add("err", "上传失败");
}
String fileName = file.getOriginalFilename();
logger.info("路径" + fileName);
String filePath = "/home/7d";
//String filePath = "E:\\test\\7d\\data\\";
File dest = new File(filePath + fileName);
String jmxName = fileName.substring(0, fileName.lastIndexOf("."));
try {
file.transferTo(dest);
logger.info("上传成功:" + jmxName);
return Msg.success().add("file", jmxName);
} catch (IOException e) {
logger.error(e.toString(), e);
}
return Msg.fail();
}/**
* 运行脚本
*
* @return
*/
@PostMapping("/JmeterRun")
@ResponseBody
public Msg run(@RequestParam("jmeterName") String jmeterName, @RequestParam("numberName") String numberName, @RequestParam("duration") String duration) {
logger.info(jmeterName);
if (!jmeterName.isEmpty() && !numberName.isEmpty()) {
jmerterScriptService.runCommand(jmeterName.trim(), numberName.trim(), duration);
return Msg.success();
} else {
return Msg.fail();
}
}/**
* 停止脚本
*
* @return
*/
@GetMapping("/JmeterStop")
@ResponseBody
public Msg stop() {
jmerterScriptService.stopCommand();
return Msg.success();
}/**
* 查看日志
*
* @return
*/
@GetMapping("/Jmeterinfo")
@ResponseBody
public Msg info() {
String info = jmerterScriptService.selectInfo();
return Msg.success().add("infopage", info);
}
}
interface层代码
package com.sevendays.service;
/**
* @author 7d
* @Title: JmerterScriptService
* @Description: Jmeterj脚本处理
* @date 2019/11/17 / 18:06
*/public interface JmerterScriptService {/**
* 执行命令
* @param cmd
*/
void execCommand(String cmd);
/**
* 运行
* @param script 脚本
* @param num数量
* @param seconds 执行时间
*/
void runCommand(String script, String num,String seconds);
/**
* 停止
*/
void stopCommand();
/**
* 获取日志
* @return
*/
String selectInfo();
}
接口实现层
package com.sevendays.service.impl;
import com.sevendays.controller.JmeterController;
import com.sevendays.service.JmerterScriptService;
import com.sevendays.utils.LogSvrReadInput;
import com.sevendays.utils.execCmd;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Date;
/**
* @author 7d
* @Title: JmerterScriptServiceImpl
* @Description: 执行命令
* @date 2019/11/17 / 18:49
*/@Service
public class JmerterScriptServiceImpl implements JmerterScriptService {private static final Logger logger = LoggerFactory.getLogger(JmerterScriptServiceImpl.class);
@Override
public void execCommand(String cmd) {
try {
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(cmd, null, null);
InputStream stderr = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(stderr, "GBK");
BufferedReader br = new BufferedReader(isr);
String line = "";
while ((line = br.readLine()) != null) {
logger.info(line);
}
} catch (Exception e) {
e.printStackTrace();
}}@Override
public void runCommand(String script, String num, String seconds) {//执行次数
String numThread = "#numThread";
//执行时间
String time = "#timeDuration";
String bak = "cp /home/7d/" + script + ".jmx /home/7d/" + script + "bak.jmx";
String old = "/home/7d/" + script + ".jmx";
execCmd.execCmd(bak);
logger.info("路径:{}", old);
//替换执行数量
execCmd.replacTextContent(old, "#numThread", num);
//替换执行时间
execCmd.replacTextContent(old, "#timeDuration", seconds);
String runcmd = "nohup jmeter -n -t /home/7d/#scriptName.jmx -l /home/7d/#scriptName.jtl -j /home/7d/jmeter.log > /home/7d/jmeterlog.log&".replaceAll("#scriptName", script);
logger.info("运行命令{}", runcmd);
execCmd.execCmd(runcmd);
}@Override
public void stopCommand() {
String stoprunm = "/root/tools/apache-jmeter-5.1.1/bin/shutdown.sh";
execCmd.execCmd(stoprunm);
}@Override
public String selectInfo() {
String tail = "tail -f /home/7d/jmeterlog.log";
File file = new File("/home/7d/jmeterlog.log");
String s = LogSvrReadInput.realtimeShowLog(file);
logger.info("输出日志:--》{}",s);
return s;
}
}
工具类
package com.sevendays.utils;
import com.sevendays.service.impl.JmerterScriptServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
/**
* @author 7d
* @Title: execCmd
* @Description: 直接执行命令
* @date 2019/11/17 / 19:17
*/public class execCmd {private static final Logger logger = LoggerFactory.getLogger(execCmd.class);
public execCmd() {
}/**
* 直接执行命令
*
* @param cmd
*/
public static void execCmd(String cmd) {
try {
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(cmd, null, null);
InputStream stderr = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(stderr, "GBK");
BufferedReader br = new BufferedReader(isr);
String line = "";
while ((line = br.readLine()) != null) {
logger.info(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}/**
* 替换文本文件中的 非法字符串
*
* @param path路径
* @param srcStr 原有的内容
* @param newStr 要替换的内容
*/
public static void replacTextContent(String path, String srcStr, String newStr) {
File file = new File(path);
if (!file.exists() && !file.isFile()) {
logger.info("file{},不存在:", path);
return;
}
try {
FileReader in = new FileReader(file);
BufferedReader bufIn = new BufferedReader(in);
// 内存流, 作为临时流
CharArrayWriter tempStream = new CharArrayWriter();
// 替换
String line = null;
while ((line = bufIn.readLine()) != null) {
// 替换每行中, 符合条件的字符串
line = line.replaceAll(srcStr, newStr);
// 将该行写入内存
tempStream.write(line);
// 添加换行符
tempStream.append(System.getProperty("line.separator"));
}
// 关闭 输入流
bufIn.close();
// 将内存中的流 写入 文件
FileWriter out = new FileWriter(file);
tempStream.writeTo(out);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
logger.info("====path:" + path);
}}
jmeter脚本 脚本其实也没有什么东西,只有定义好规则,这样方便替换。
文章图片
小结 上面 Demo 中还是一个问题没有解决就是在页面实时参看日志,目前还没实现,不过总体上实现自己想的功能。
源码地址:
- https://github.com/zuozewei/blog-example/tree/master/Performance-testing/01-test-tool/jmeter/seven_days
推荐阅读
- Java|Java基础——数组
- 人工智能|干货!人体姿态估计与运动预测
- java简介|Java是什么(Java能用来干什么?)
- Java|规范的打印日志
- Linux|109 个实用 shell 脚本
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- Spring注解驱动第十讲--@Autowired使用
- =======j2ee|spring用注解实现注入的@resource,@autowired,@inject区别