Jmeter通过Springboot工程启动的实现过程

发表于:2020-9-18 10:43

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:返回主页 AlamZ    来源:博客园

  背景
  Jmeter平时性能测试工作一般都是通过命令行在linux下执行,为了锻炼自己代码与逻辑能力,想jmeter是否可以通过springboot工程启动,周末在家尝试写一写,一写原来需要处理很多事情,才可以启动起来,起来还是有很问题需要处理,下面是相应的代码,其实网上也有,但关键的是自己有意识收集知识,到用的时候能拿来改一改就用。
  启动页面:
   
  前置条件
  需要在linux中配置Jmeter成功,并且配置环境变量:
   
  环境配置:
  编辑:
  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
  点击上传脚本,弹出对话框,点击上传,后台日志显示上传成功:
  点击启动:并且读取启动日志
  点击停止:
  上面脚本停止
  图画说明:
  通过访问--》调用java代码--》启动shell命令--》启动jmeter-获取启动日志
  前端代码
  以下参考代码,大家可以学习学习
  <a class="btn btn-success" onclick="JmeterRun()" type="submit">运行</a>
              <a class="btn btn-danger" onclick="Jmeterstop()" type="submit">停止</a>
              <a class="btn btn-info" onclick="JmeterInfo()" data-toggle="modal" data-target="#myModal">查看信息</a>
   
   
  <script>
      //上传脚本
      function submitupload() {
          var type = "file";              //后台接收时需要的参数名称,自定义即可
          var id = "jmeterId";            //即input的id,用来寻找值
          var formData = new FormData();
          var jmeterId = $("#jmeterId").val();
          if (jmeterId == "") {
              layer.msg("Jmeter文件不能为空,请输入", {time: 2000, icon: 5, shift: 6}, function () {
              });
              return;
          }
          formData.append(type, $("#" + id)[0].files[0]);
          $.ajax({
              type: "POST",
              url: '/jmeter/upload',
              data: formData,
              processData: false,
              contentType: false,
              success: function (data) {
                  if (data.code == 100) {
                      layer.msg("用户信息保存成功", {time: 1000, icon: 6}, function () {
                          // console.log("相应结果:" + data.extend.file);
                          //通过返回结果进行赋值
                          $("#jmeterName").val(data.extend.file);
                          // window.location.href = "/jmeterIndex";
                      });
                  } else {
                      layer.msg("信息保存失败,请重新操作" + data.err, {time: 2000, icon: 5, shift: 6}, function () {
   
                      });
                  }
              }
          });
      }
   
      //上传参数
      function submitParm() {
          var type = "file";              //后台接收时需要的参数名称,自定义即可
          var id = "jmeterParam";            //即input的id,用来寻找值
          var formData = new FormData();
          var jmeterPara = $("#jmeterParam").val();
          if (jmeterPara == "") {
              layer.msg("Jmeter文件不能为空,请输入", {time: 2000, icon: 5, shift: 6}, function () {
              });
              return;
          }
          formData.append(type, $("#" + id)[0].files[0]);
          $.ajax({
              type: "POST",
              url: '/jmeter/Paramupload',
              data: formData,
              processData: false,
              contentType: false,
              success: function (data) {
                  if (data.code == 100) {
                      layer.msg("参数文件保存成功", {time: 1000, icon: 6}, function () {
                      });
                  } else {
                      layer.msg("信息保存失败,请重新操作" + data.err, {time: 2000, icon: 5, shift: 6}, function () {
   
                      });
                  }
              }
          });
      }
   
      //运行
      function JmeterRun() {
          let JmeterName = $("#jmeterName").val();
          let number = $("#numberName").val();
          let duration = $("#duration").val();
   
          console.log(JmeterName);
          console.log(number);
          $.ajax({
              type: "POST",
              url: '/jmeter/JmeterRun',
              data: {
                  "jmeterName": JmeterName,
                  "numberName": number,
                  "duration": duration
              },
              success: function (result) {
                  if (result.code == 100) {
                      layer.msg("启动成功成功", {time: 1000, icon: 6}, function () {
                      });
                  } else {
                      layer.msg("启动失败,请重新操作", {time: 2000, icon: 5, shift: 6}, function () {
   
                      });
                  }
              }
          })
      }
   
      //停止
      function Jmeterstop() {
          $.ajax({
              type: "Get",
              url: '/jmeter/JmeterStop',
              processData: false,
              contentType: false,
              success: function (result) {
                  if (result.code==100) {
                      layer.msg("停止成功", {time: 1000, icon: 6}, function () {
                      });
                  } else {
                      layer.msg("停止失败,请重新操作", {time: 2000, icon: 5, shift: 6}, function () {
   
                      });
                  }
              }
          })
   
      }
   
      //查看日志
      function JmeterInfo() {
          $.ajax({
              type: "Get",
              url: '/jmeter/Jmeterinfo',
              processData: false,
              contentType: false,
              success: function (result) {
                  if (result.code == 100) {
                      layer.msg("启动成功成功", {time: 1000, icon: 6}, function () {
                          $("#JmeterMsg").val(data.extend.infopage);
                      });
                  } else {
                      layer.msg("启动失败,请重新操作", {time: 2000, icon: 5, shift: 6}, function () {
   
                      });
                  }
              }
          })
      }
   
   
  </script>
  后端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 liwen
   * @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层代码
  /**
   * @author liwen
   * @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();
   
  }
  接口实现层
  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 liwen
   * @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 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;
      }
   
   
  }
  工具类
  /**
   * 直接执行命令
   *
   * @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();
      }
  }
  jmeter脚本:
  脚本其实也没有什么东西,只有定义好规则,这样方便替换。
  GitHub 地址:
  https://github.com/357712148/bodygit.git
  小结:
  做性能测试代码能力,不是关键,但是是晋升一个必要条件,而且在项目性能分析还是需要懂一些代码能力,这样与研发,DBA、运维能谈的来。
  上面存在的问题:
  上面deme中还是一个问题没有解决就是在页面实时参看日志,目前还没实现,不过总体上实现自己想的功能。

  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理   
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号