[转]性能工具之Jmeter通过springboot工程启动

背景

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中还是一个问题没有解决就是在页面实时参看日志,目前还没实现,不过总体上实现自己想的功能。

 

 

posted @ 2020-09-16 17:03  AlamZ  阅读(544)  评论(0编辑  收藏  举报