基于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代码,会写 ...
随机推荐
- 【LOJ】#3043. 「ZJOI2019」线段树
LOJ#3043. 「ZJOI2019」线段树 计数转期望的一道好题-- 每个点设两个变量\(p,q\)表示这个点有\(p\)的概率有标记,有\(q\)的概率到祖先的路径上有个标记 被覆盖的点$0.5 ...
- 【LOJ】#3123. 「CTS2019 | CTSC2019」重复
LOJ3123 60pts 正难则反,熟练转成总方案数减掉每个片段都大于等于s的字典序的方案 按照一般的套路建出kmp上每个点加一个字符的转移边的图(注意这个图开始字母必须是nxt链中下一个相邻的字符 ...
- 新浪随机图片壁纸API接口 刷新网页换背景接口
刷新一次页面换一次图片,可以调用到你的网站背景里面去,多炫酷啊,刷新一下本页看下效果哦. 说明:随机图片壁纸api,调用的是新浪api,速度不用担心,图片资源也很多 电脑动漫图片:http://api ...
- dos2unix、diff命令
一.dos2unix:将DOS格式文件转化成UNIX格式文件 语法: dos2unix [选项] [文件...] [-n INFILE输出文件...] unix2dos [选项] ...
- 刨根究底字符编码之十——Unicode字符集的编码方式以及码点、码元
Unicode字符集的编码方式以及码点.码元 一.字符编码方式CEF的选择 1. 由于Unicode字符集非常大,有些字符的编号(码点值)需要两个或两个以上字节来表示,而要对这样的编号进行编码,也必须 ...
- Open-falcon监控
https://book.open-falcon.org/zh_0_2/ 本文档记录了CentOS7.4下open-falcon-v2监控系统的部署流程,以及一些需要注意的地方. 环境准备 安装Red ...
- Java Serializable Objects(序列化)
https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html 序列化一个对象,意味着把这个对象的状态转化为字节流,而且个字节流 ...
- Ubuntu系统开机后不能正常使用——问题解决记录
1.开机后桌面内容没了,搜狗输入法不能使用了,终端不能打开了 问题原因:上次关机前为了解决解压文件中文乱码问题,在/etc/profile末尾加了如下两行:(但事实上如下两行根本不能解决中文乱码问题) ...
- Winfrom 定时锁屏
#region 锁屏 public struct LASTINPUTINFO { [MarshalAs(UnmanagedType.U4)] public int cbSize; [MarshalAs ...
- 【原创】大数据基础之Gobblin(2)持久化kafka到hdfs
gobblin 0.10 想要持久化kafka到hdfs有很多种方式,比如flume.logstash.gobblin,其中flume和logstash是流式的,gobblin是批处理式的,gobbl ...