基于locust的性能测试平台搭建
前段时间加入性能测试组,并参与搭建基于locust的性能测试平台,我分到的任务相对独立,开发locust的启动接口和停止运行接口,现开发的差不多了,做一个总结
一、locust运行的相关内容

二、locust操作相关的linux命令
启动locust:"locust -f /usr/fin/FinBomber/LF_"+taskCode+".py --host="+host+" -P "+port
杀掉所有在运行的locust进程:ps -ef |grep locust|grep -v grep | awk '{print $2}' | xargs kill -9
获取所有在运行的locust进程:ps -ef |grep locust|grep -v grep | awk '{print $2}'
获取指定port对应的pid:"/usr/sbin/lsof -i:"+port+"|grep -v grep | awk '{print $2}'|awk 'NR==2{print}'"
杀掉该pid:"kill -9 "+locustPid
三、接口编写思路
1.编写两个接口,一个启动,同时更新数据库相关字段,另一个为停止运行,同时更新数据库相关字段。如下图


2.代码敲着敲着问题就暴露了
问题:java连linux执行启动locust命令(locust -f /usr/fin/FinBomber/LF_"+taskCode+".py --host="+host+" -P "+port),启动是启动了,但是会一直卡那,代码不会继续往下走(往下主要是执行更新数据库操作,后续停止运行接口才能获取到pid,从而杀掉进程),完全不知道咋整,一度觉得整不出来的时候,灵光一现
解决方法:既然启动命令可以完成启动,只是不能继续往下走代码,那就让它别走了,再开一个接口来完成这件事不就好了,傻缺!瞬间觉得我真是天才
最终方案:启动编写两个接口,一个启动,一个更新数据库
-------------------------------解决方法更新---------------------------------
用多线程!!!!瞬间觉得自己之前真是井底之蛙
四、上代码
java连接linux执行命令代码如下:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.ServerSocket; import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler; public class LinuxCommandUtil {
private static final Logger log = LoggerFactory.getLogger(LinuxCommandUtil.class);
private static String DEFAULTCHART="UTF-8";
/**
* 登录主机
* @return
* 登录成功返回true,否则返回false
*/
public static Connection login(String ip,
String userName,
String userPwd){ boolean flg=false;
Connection conn = null;
try {
conn = new Connection(ip);
conn.connect();//连接
flg=conn.authenticateWithPassword(userName, userPwd);//认证
if(flg){
log.info("=========登录成功========="+conn);
return conn;
}
} catch (IOException e) {
log.error("=========登录失败========="+e.getMessage());
e.printStackTrace();
}
return conn;
} /**
* 远程执行shll脚本或者命令
* @param cmd
* 即将执行的命令
* @return
* 命令执行完后返回的结果值
*/
public static String execute(Connection conn,String cmd){
String result="";
try {
if(conn !=null){
Session session= conn.openSession();//打开一个会话
session.execCommand(String.valueOf(cmd));//执行命令
result=processStdout(session.getStdout(),DEFAULTCHART);
//如果为得到标准输出为空,说明脚本执行出错了
if(StringUtils.isBlank(result)){
log.info("得到标准输出为空,链接conn:"+conn+",执行的命令:"+cmd);
result=processStdout(session.getStderr(),DEFAULTCHART);
}else{
log.info("执行命令成功,链接conn:"+conn+",执行的命令:"+cmd);
}
conn.close();
session.close();
}
} catch (IOException e) {
log.info("执行命令失败,链接conn:"+conn+",执行的命令:"+cmd+" "+e.getMessage());
e.printStackTrace();
}
return result;
}
/**
* 解析脚本执行返回的结果集
* @param in 输入流对象
* @param charset 编码
* @return
* 以纯文本的格式返回
*/
public static String processStdout(InputStream in, String charset){
InputStream stdout = new StreamGobbler(in);
StringBuffer buffer = new StringBuffer();;
try {
BufferedReader br = new BufferedReader(new InputStreamReader(stdout,charset));
String line=null;
while((line=br.readLine()) != null){
buffer.append(line+"\n");
}
} catch (UnsupportedEncodingException e) {
log.error("解析脚本出错:"+e.getMessage());
e.printStackTrace();
} catch (IOException e) {
log.error("解析脚本出错:"+e.getMessage());
e.printStackTrace();
}
return buffer.toString();
}
//获取未占用的端口号
public static String getFreePort(){
ServerSocket serverSocket = null; //读取空闲的可用端口
String localIp = null;
try {
serverSocket = new ServerSocket(0);
localIp = serverSocket.getInetAddress().getLocalHost().getHostAddress();
} catch (IOException e) {
e.printStackTrace();
}
String port = String.valueOf(serverSocket.getLocalPort());
System.out.println("系统分配的端口号 port="+port);
System.out.println("当前本机ip:"+localIp);
//获取当前进程ID
String processName =
java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
System.out.println("当前进程ID:"+Long.parseLong(processName.split("@")[0]));
return port;
}
public static String execLocalCmd(String cmd){
String line="";
try{
Runtime rt = Runtime.getRuntime();
//执行命令, 最后一个参数,可以使用new File("path")指定运行的命令的位置
Process proc = rt.exec(cmd,null,null);
InputStream stderr = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(stderr,"GBK");
BufferedReader br = new BufferedReader(isr); while ((line = br.readLine()) != null) { // 打印出命令执行的结果
System.out.println(line);
}
}catch (Exception e){
e.printStackTrace();
}
return line; }
public static void main(String[] args) {
// long currentTimeMillis = System.currentTimeMillis();
String ip = "X.X.X.X";
String username = "XXX";
String password = "XXXXXX";
// String cmd = "sh runLocust.sh";
String cmd = "ps -ef |grep locust|grep -v grep | awk '{print $2}' | xargs kill -9";
Connection connection = login(ip, username, password);
String execmd = execute(connection, cmd);
// System.out.println(execmd);
// long currentTimeMillis1 = System.currentTimeMillis();
// System.out.println("ganymed-ssh2方式"+(currentTimeMillis1-currentTimeMillis));
getFreePort();
} }
基于locust的性能测试平台搭建的更多相关文章
- 基于认证的代理平台搭建配置squid-20130730
基于认证的代理平台搭建配置squid-20130730 功能:通过squid代理实现 (1)基于用户名密码认证的出口ip路由选择 (2)基于client源ip的出口ip路由选择 (3)基于连接本机ip ...
- nGrinder性能测试平台搭建(LVS压力测试)
1. nGrinder是什么 nGrinder是一个免费的.开放源代码的Web性能测试平台.运行在应用中间件服务器中运行.它由一个控制端和多个代理端组成.通过控制端(浏览器访问)建立测试场景,然后通过 ...
- 基于jmeter的性能测试平台(一)分布式jmeter搭建
(1)概述 一台windows虚拟机作为controller,3台Linux虚拟机作为agent. 第一步是在所有虚拟机上安装JDK,版本最好是一样的,然后就是下载安装jmeter,网上资料很多这里不 ...
- 基于jmeter的性能测试平台(二) 一个构想
之前基于jmeter搭好了分布式测试平台,但是感觉还是很粗糙,打算给它穿点衣服. 整个架构差不多就像下面这个图. (1)基于python django做一个web页面,友好地管理测试过程 (2)con ...
- 基于Docker在Win10平台搭建Ruby on Rails 6.0框架开发环境
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_170 2020年,"非著名Web框架"–Ruby on Rails已经15岁了.在今年,Rails 6.0趋于 ...
- 基于Ubuntu的ESP32平台搭建
提要:针对于Ubuntu下的ESP32搭建,网上有很多博文,乐鑫官网也有指导手册,对于到家都知道的部分我就一带而过,我主要描述搭建过程中遇到的问题和细节. 1.创建一个ESP的目录 I)在家目录下创建 ...
- 基于Moodle的IT课程辅助教育平台搭建
基于Moodle的IT课程辅助教育平台搭建 Moodle是一个开源课程管理系统(CMS),也被称为学习管理系统(LMS)或虚拟学习环境(VLE).它已成为深受世界各地教育工作者喜爱的一种为学生建立网上 ...
- 基于MyEclipse+9.0+++Tomcat+7.0的SSH+平台搭建
基于MyEclipse+9.0+++Tomcat+7.0的SSH+平台搭建 http://wenku.baidu.com/view/96fbfe0f581b6bd97f19ea1d.html 用MyE ...
- 基于python的性能测试工具–locust
现在有很多的性能测试工具,比如说我们熟悉的loadrunner.jmeter.ab.webbench等等,这些工具如果对一个没用过的朋友来说,学习起来比较不容易,但是如果你能看懂python代码,会写 ...
随机推荐
- 大数据之Zookeeper概述
Zookeeper概述 Zookeeper是一个开放源码的分布式应用程序协调服务,是 Google的Chubby一个开源的实现,是 Hadoop和 HBASE的重要组件.主要解决分布式应用一致性问题. ...
- 【LOJ】#3083. 「GXOI / GZOI2019」与或和
LOJ#3083. 「GXOI / GZOI2019」与或和 显然是先拆位,AND的答案是所有数字为1的子矩阵的个数 OR是所有的子矩阵个数减去所有数字为0的子矩阵的个数 子矩阵怎么求可以记录每个位置 ...
- 2019CSP-S游记
\(2019CSP-S\)游记 \(Day : -26\) 初赛退役失败,准备复赛了... \(Day:0\) 早上\(7:30\)出发坐车去杭州,车上一直在听歌和睡觉中度过(话说锦零的歌真好听).. ...
- django form组件 cookies,session
django form组件 渲染标签 就是组件里面的字段在前端展示叫做渲染标签 校验数据 用户输入的数据提交给后端组件叫做校验数据 forms组件中定义的字段都是必须传值的(required=Tr ...
- 并不对劲的复健训练-bzoj5253:loj2479:p4384:[2018多省联考]制胡窜
题目大意 给出一个字符串\(S\),长度为\(n\)(\(n\leq 10^5\)),\(S[l:r]\)表示\(S_l,S_{l+1}...,S_r\)这个子串.有\(m\)(\(m\leq 3\t ...
- 怎样理解NodeList的动态集合与静态集合
NodeList 有两种, 一种是动态集合, 一种是静态集合, 所谓动态集合, 主要是 Node.prototype.childNodes; 返回的子节点集合对文档的节点增删改会即时改变; 而静态集合 ...
- JDBC 24homework
编写程序: 1. 创建商品信息表Goods(包含编号Code.名称Name.数量Number.单价Price) 2. 设计程序流程,由用户选择:插入.删除.修改.查询 程序效果如下: (1)根据提示输 ...
- 修改this的指向
call var a={ name:'xuux', fn:function(a,b){ console.log(a+b); console.log(this);//{name: "xuux& ...
- 图片上传(3)(组件 -- 图片大小宽高限制)base64图片宽高读取
1.上传组件(可上传多个文件) <template> <div class="attachmentN"> <span class="btnS ...
- linux PDF转换
在libre-office以安装的情况下 soffice --convert-to pdf *.odt --invisible