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

     
  • 相关阅读:
    HDU--4548 美素数
    【思维】南阳理工 14 会场安排问题
    【思维】【水】 南阳oj 喷水装置(一)
    【思维】南阳理工91 阶乘之和
    【转】哈夫曼树 九度1172
    Array
    HDU--1702 ACboy needs your help again!
    栈和队列
    3.Compound data types
    4.Object Oriented Programming
  • 原文地址:https://www.cnblogs.com/alamZ/p/13680114.html
Copyright © 2020-2023  润新知