前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >性能工具之Jmeter通过springboot工程启动

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

作者头像
高楼Zee
发布2019-11-25 16:15:29
2K0
发布2019-11-25 16:15:29
举报
文章被收录于专栏:7DGroup7DGroup

背景

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-获取启动日志

前端代码

以下参考代码,大家可以学习学习

代码语言:javascript
复制
<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

代码语言:javascript
复制
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层代码

代码语言:javascript
复制
/**
 * @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();

}

接口实现层

代码语言:javascript
复制
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;
    }


}

工具类

代码语言:javascript
复制
/**
 * 直接执行命令
 *
 * @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中还是一个问题没有解决就是在页面实时参看日志,目前还没实现,不过总体上实现自己想的功能。

送大家一句诗:

蜀道难

【作者】李白 【朝代】唐

噫吁嚱,危乎高哉!蜀道之难,难于上青天!蚕丛及鱼凫,开国何茫然!尔来四万八千岁,不与秦塞通人烟。西当太白有鸟道,可以横绝峨眉巅。地崩山摧壮士死,然后天梯石栈相钩连。上有六龙回日之高标,下有冲波逆折之回川。黄鹤之飞尚不得过,猿猱欲度愁攀援。青泥何盘盘,百步九折萦岩峦。扪参历井仰胁息,以手抚膺坐长叹。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 7DGroup 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 前置条件
    • 前端代码
    • 后端Controller
    • interface层代码
      • 接口实现层
        • 工具类
        • jmeter脚本:
        • GitHub 地址:
        • 小结:
        • 上面存在的问题:
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档