Easy-Jmeter: 性能测试平台

news2025/1/19 8:01:11

目录

  • 写在开始
  • 1 系统架构
  • 2 表结构设计
  • 3 测试平台生命周期
  • 4 分布式压测
  • 5 压力机管理
  • 6 用例管理
    • 6.1 新增、编辑用例
    • 6.2 调试用例
    • 6.3 启动测试
    • 6.4 动态控量
    • 6.5 测试详情
    • 6.6 环节日志
    • 6.7 实时数据
    • 6.8 测试结果
  • 7 测试记录
  • 7 用例分析
  • 8 系统部署
    • 8.1普通部署
    • 8.2容器化部署
  • 写在最后

写在开始

    在经历了一段相对较长的时间后,在最近我完成了性能测试平台初版的所有功能,这是我在跨越近一年时间中的最大收获。最初有看到网上有个人或团队开发的性能测试平台,就在想如果要实现这么一个工具,这个工具应该是什么样子,应该怎样去做。那时我个人写的接口自动化测试平台已经在公司小范围的使用,同时在不断的优化功能,便暂时将其保留为一个想法。在去年打算将这个想法变为现实,便一点一点的摸索与思考,一点一点的将其实现。由于只是利用业余时间,并且这个过程遇到不少困难,这个系统的实现跨越了较长的时间。相比较之前实现的接口自动化测试平台,这次在做性能测试平台时一个比较大的进步是在开始写代码前,设计阶段准备的充分很多,这次做了完整的原型,不再是一边写一边设计新页面。
    开源工具在功能和专业性上已经足够好了,为什么还要做平台化,平台化的意义是什么呢?我认为工具平台化的好处有以下几点:1.方便团队协作和数据整合:开源工具大多是C/S架构的,不利于团队之间共享和交互,也无法归集和整合历史数据;2.定制化功能:平台化在开源工具的基础上可以结合业务实现自定义功能,与外部系统对接,使得测试变得更加灵活和方便;3.降低成本:界面化比原有系统会操作相对简单,降低了压测环境的维护成本、操作成本和管理成本;4.个人提升:提升个人在代码、性能测试方面的深度。
    目前有非常多的开源性能测试工具,它们的功能都非常完备和成熟,所以在最开始,设计的理念就是在压测功能上尽可能的复用成熟工具的功能。jmeter作为一个开源的性能测试工具,在业内具有权威性的地位,所以这个性能测试平台基于jmeter进行开发。技术栈使用vue+springboot前后端分离,基础的业务框架使用开源的Lin-CMS管理系统,其提供用户、权限、认证等基础功能。数据库使用mysql5.7、mongodb4.2、influxdb1.8,文件存储使用minio文件服务器。实现了用例与测试数据管理、分布式压力测试、实时压测数据查看、测试结果查看与下载、历史测试数据查询和测试结果分析等功能。

源码地址:https://github.com/guojiaxing1995/easy-jmeter
原型地址:https://modao.cc/app/Qf56LAncrokbxs3iOBMRap

EasyJmeter性能测试平台

1 系统架构

系统架构
用户访问web页面,再由页面通过http请求访问业务后端服务。每台压力机服务器(只支持linux)上有且仅有一个jmeter,同时安装一个agent来控制jmeter运行,agent和服务端使用socketio实时通讯,用于服务端下发指令和agent上报状态。业务数据使用mysql进行存储,测试结果的详细数据使用mongodb存储,压测过程中的热数据使用influxdb存储,测试用例脚本、压测数据文件和压测结果文件(日志、jtl、报告)使用minio文件服务器存储。

2 表结构设计

mysql中除去原本CMS框架系统自带的表,测试平台业务表有6张

表名描述
project工程表,管理测试用例的单位
machine压力机表,管理压力机
file文件表
case用例表
task记录表,记录一次压测执行
task_log记录日志表

mongodb中业务集合有2个

集合名描述
reportjmeter报告数据
statistics单个用例的历史整合数据

3 测试平台生命周期

在这里插入图片描述

平台化对压测进行管理,就要定义一次性能测试的各个阶段,这些阶段组成了压测平台的生命周期。生命周期包含了四个阶段,分别是配置、运行、收集和清理。配置阶段主要为将测试所需的数据如jmx脚本、csv文件、扩展jar文件从minio下载到各个压力机,将需要切分的csv文件进行切分,切分就是将一个csv文件内的数据按照压力机的个数分为多份,最后配置脚本和配置文件等参数。配置成功后agent向服务端报告状态,待所有压力机配置完成服务端下发运行指令,进入压测状态,压测状态为jmeter持续运行中并收集测试数据。所有压力机运行完成上报后统一进入收集状态,上传测试结果文件并对结果进行处理并归集。所有压力机都完成收集后进入清理状态,每台压力机重置测试环境。在这一系列阶段中,平台不能丢失对各个阶段的管理,系统在当前阶段出现问题后要可以闭环,所以前三个阶段失败后都会进入清理阶段。同时可以手动的停止前三个阶段,终止压力测试。

4 分布式压测

jmeter本身是支持分布式压测的,但存在一些缺陷,如需要不少额外配置,master节点不参与压测浪费资源,测试数据实时回传master浪费带宽。压测平台本身就已经实现通过agent控制jmeter,agent和服务端通过长连接进行实时通信,在此基础上,由服务端控制各个压力机运行,平台就实现了对于压力机的分布式调度。

5 压力机管理

压力机管理
一台压力机上部署一个agent服务和jmeter,jmeter需要将其安装路径设置为环境变量JMETER_HOME,agent根据环境变量定位jmeter,每分钟判断一次jmeter是否可用并上报ip、版本、路径给服务端,和服务端维护的ip地址匹配作为压力机是否在线的依据,匹配一致的压力机会更新jmeter的版本和安装路径。

6 用例管理

用例列表
用例管理可以新增、编辑、查询、调试、删除用例,可以对目标用例进行启动测试、终止测试、查看测试详情、动态控制TPS和跳转用例的历史记录列表。

6.1 新增、编辑用例

编辑用例

用例新增、编辑时填写用例名称、选择项目,项目为当前系统维护,用来进行用例分类。
上传保存好的jmx文件、csv文件、jar文件,csv文件可选是否切分。

6.2 调试用例

在列表页面点击调试按钮,可以打开调试弹框,点击启动对当前用例以一个线程发起一次请求.如查看结果树一样,可以查看接口的响应和请求信息。
在这里插入图片描述
点击引擎日志,可以查看对应请求的jmeter日志
在这里插入图片描述

6.3 启动测试

在这里插入图片描述

在列表点击启动按钮弹出测试启动弹框,选择运行的并发线程数、压测时间、启动线程的时间、容量控制,容量控制会在下文详细展开。压力机可以选择个数或指定某几台压力机。日志等级为jmeter日志等级。报告时间颗粒度为jmeter生成报告图表的时间采样频率,默认0为系统内置采样率,为0时系统会根据压测时间来设置采样间隔。实时数据展示开关控制本次测试是否记录实时数据并展示。
在测试过程中可以通过列表或详情的进度条查看当前的状态,运行状态的测试可以查看已运行时间的百分比。

6.4 动态控量

这里的动态控量是指吞吐量的限制与动态调节。这个高阶知识点最早是在其他文章中看到的。
在压测时,“控量”是非常重要的,JMeter 是根据线程数大小来控制压力强弱的,但我们制定的压测目标中的指标往往是吞吐量(QPS/TPS),这就给测试人员带来了不便之处,必须一边调整线程数,一边观察QPS/TPS 达到什么量级了。为了解决这个问题,JMeter 提供了吞吐量控制器的插件,我们可以通过设定吞吐量上限来限制 QPS/TPS,达到控量的效果。
在这里插入图片描述
上面的做法能够确保将吞吐量控制在一个固定值上,但这样还远远不够,实际工作中我们希望在每次压测执行时能够随时调节吞吐量,比如,在某个压力下服务容量没有问题,我们希望在不停止压测的情况下,再加一些压力。方案就是将目标吞吐量设置为变量,在测试过程中调整这个值。
在这里插入图片描述
修改jmeter.properties参数

#---------------------------------------------------------------------------
# BeanShell configuration
#---------------------------------------------------------------------------
 
# BeanShell Server properties
#
# Define the port number as non-zero to start the http server on that port
beanshell.server.port=9000
# The telnet server will be started on the next port

# Define the server initialisation file
beanshell.server.file=../extras/startup.bsh

执行测试过程中,通过外部命令访问BeanShell服务就能植入我们的BeanShell脚本和全局变量

java -jar <jmeter_path>/lib/bshclient.jar localhost 9000 update.bsh <参数>

自定义的吞吐量更新脚本update.bsh如下:

import org.apache.jmeter.util.JMeterUtils;
 
getprop(p){ // get a JMeter property
    return JMeterUtils.getPropDefault(p,"");
}
 
setprop(p,v){ // set a JMeter property
    print("Setting property '"+p+"' to '"+v+"'.");
    JMeterUtils.getJMeterProperties().setProperty(p, v);
}
setprop("throughput", args[0]);

在平台中可以通过页面修改吞吐量限制
在这里插入图片描述

6.5 测试详情

在这里插入图片描述
点击用例进入目标用例最近一次测试的详情页面,进行中的用例会展示测试进度。顶部显示用例的基础信息,下方显示测试情况,有并发线程数、压测时长、测试人员、压测开始结束时间、压力机台数,可以下载jmeter日志、测试脚本文件。测试完成后会显示聚合报告。

6.6 环节日志

在这里插入图片描述

测试时实时展示测试阶段每一个环节的进度以及对应环节下每一台压力机的环节结果。更好的管理生产周期状态和排查问题。

6.7 实时数据

在这里插入图片描述
在这里插入图片描述

jmeter支持 Backend Listener 将测试结果实时发往 InfluxDB,平台向 InfluxDB 轮询查询数据,并展示在页面上。目前展示了总TPS、总错误趋势、错误事务统计,以及指定事务筛选,查看对应事务TPS、错误趋势和错误类型分类。除此以外,也可以集成开源数据可视化系统Grafana,进行更加丰富的数据展示。

6.8 测试结果

图表报告1
在这里插入图片描述
在这里插入图片描述
在测试完成后,可以查看测试图表信息,包含TPS、平均响应时间、总TPS、随时间变化的响应时间百分位数(成功响应)、活动线程数共5个图表,以及错误类型占比和错误排行榜top5。点击右上角报告下载按钮,下载jmeter测试报告可查看更多详细数据。

7 测试记录

在这里插入图片描述
测试记录模块可以查看所有的测试记录,支持按照测试编号、用例名称、测试时间、测试结果进行查询。点击详情跳转对应记录的测试详情页,

7 用例分析

在这里插入图片描述
顶部可查看系统数据,包含项目数、用例数、压力机数、测试次数、压测总时长以及总请求数。
左侧为用例列表,支持查看指定用例的平均响应时间、90th响应时间、平均吞吐量、测试次数、压测时长和请求数。支持查看多次测试的响应时间趋势、吞吐量和错误率,可以帮助测试与开发人员在系统优化后,一目了然的查看优化情况。

8 系统部署

8.1普通部署

  1. 安装mysql5.7数据库
  2. 安装mongodb4.2数据库
  3. 安装influxdb1.8数据库
  4. 安装minio文件服务器,设置指定bucket的Access Policy为public
  5. 部署server、agent。代码结构中api目录下为后端目录,后端使用springboot,修改配置文件并打包。其中作为server启动时设置socket.server.enable为true,作为agent启动时设置socket.client.enable为true,agent需要设置服务端socketio地址serverUrl。agent所在压力机需要配置jmete安装路径作为环境变量JMETER_HOME.
  6. 前端服务打包。代码结构中web目录下为前端服务,前端使用vue,node版本v12.13.0,打包命令 npm run build。
  7. 安装nginx。将web目录下default.conf按照实际情况修改,将前端包和配置文件放入nginx指定目录下启动。

8.2容器化部署

  1. 构建后端jar包,代码结构中api目录下为后端目录,后端框架springboot,maven构建命令,mvn clean package
  2. 构建前端dist包,前端使用vue,node版本v12.13.0,打包命令 npm run build
  3. 编辑项目根目录下docker-compose.yaml 文件,修改environment中的minio地址和influxdb地址为实际地址,修改volumes中宿主机jmeter地址为实际地址。项目根目录下执行docker-compose up -d构建镜像并启动。

写在最后

    对于测试工具或其他效能工具,我认为它最重要的就是要好用,这一点涉及到页面交互、功能设计等放放面面。之前做的接口自动化测试平台,有的同事认为可以方便的实现接口的测试,但也有同事认为在使用上还不够友好,我也持续进行了优化,并增加了一些功能,最终还算满意。但后期不管怎样去改,它的基本功能结构在一开始就已经定了,所以设计阶段的工作尤其重要,这次在设计上投入了不少时间。但很多事情并不能等完全想明白再去做,因为有时候事情存在难度、在遇到困难时是没有办法完全理清的,遇到这种时候,就在尽可能准备充分后下手去做,迈开第一步。
    测试平台已经具备了基本的性能测试功能。目前只进行了初步的使用,在后续结合实际业务使用中,我会不断进行功能优化。如果有好的想法和建议,欢迎随时沟通。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1470039.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

opencv基础 python与c++

question: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple matplotlib Opencv 一、读取图片 (1).imshow Mat imread(const string& filename, intflags1 );flags: enum { /* 8bit, color or not */CV_LOAD_IMAGE_UNCHANGED -1, /* 8bit, gray */CV_LOAD_I…

小白水平理解面试经典题目LeetCode 404 Sum of Left Leaves【Tree】

404 左叶之和 小白翻译 给定二叉树的root&#xff0c;返回所有左叶的总和。 叶子是没有子节点的节点。左叶是另一个节点的左子节点的叶。 例子 小白教室做题 在大学某个自习的下午&#xff0c;小白坐在教室看到这道题。想想自己曾经和白月光做题&#xff0c;现在大过年的&a…

使用Templ进行Go模板化

使用Templ在Go项目中高效生成动态内容的指南 动态内容生成是Web开发的一个基本方面。无论您是在构建网站、Web应用程序还是API&#xff0c;根据数据和模板生成动态内容的能力都至关重要。在Go编程世界中&#xff0c;一个名为“Templ”的强大工具简化了这一过程。在这份全面的指…

【Crypto | CTF】BugKu 简单的RSA

天命&#xff1a;这题也不算简单了&#xff0c;要反编译&#xff0c;要灵活一点 首先收到pyc文件&#xff0c;拿去反编译出来&#xff0c;可以用在线反编译&#xff0c;也可以用工具反编译 在线&#xff1a;python反编译 - 在线工具 工具&#xff1a;https://download.csdn.n…

Vue packages version mismatch 报错解决

问题 npm run dev 运行项目的过程中&#xff0c;报错 Vue packages version mismatch 解决方法 根据报错不难看出是 vue 与 vue-template-compiler 版本产生了冲突&#xff0c;vue 与 vue-template-compiler 的版本是需要匹配的。所以解决的办法就是先修改其中一个的版本将 v…

Linux环境下C语言实现ping命令

Linux环境下C语言实现ping命令 涉及的知识点 Linux信号量的使用 SIGALRM信号是操作系统中的其中一个信号。他的作用是设置进程隔多久后会收到一个SIGALRM信号 #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <signal.h> …

AI赋能Oracle DBA:以自然语言与Oracle数据库互动

DBA AI助手&#xff1a;以自然语言与Oracle数据库互动 0. 引言1. AI赋能Oracle DBA的优势2. AI如何与Oracle数据库交互3. 自然语言查询的一些示例4. 未来展望 0. 引言 传统的Oracle数据库管理 (DBA) 依赖于人工操作&#xff0c;包括编写复杂的SQL语句、分析性能指标和解决各种…

PHP语言检测用户输入密码及调用Python脚本

现在有一份计算流体力学N-S方程的Python脚本&#xff0c;想要在用户登录网站后可以可以运行该脚本&#xff0c;然后将脚本运行后绘制的图片显示在用户网页上。 建一个名为N_S.py的python脚本文件&#xff0c;这个脚本在生成图像后会自行关闭&#xff0c;随后将图片保存在指定的…

【读文献】DynamicBind生成式模型预测蛋白配体复合物

published at nature communication (2024.01.24) code link paper link 摘要 尽管在预测静态蛋白质结构方面取得了重大进展&#xff0c;但蛋白质的内在动态性&#xff0c;受到配体调节&#xff0c;对于理解蛋白质功能和促进药物发现至关重要。 传统的对接方法&#xff0c;常…

JDK9新特性:Java9的编程革新之旅

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

人工智能 — 点云模型

目录 一、点云模型1、三维图像2、点云1、概念2、内容 3、点云处理的三个层次1、低层次处理方法2、中层次处理方法3、高层次处理方法 二、Spin image 一、点云模型 1、三维图像 三维图像是一种特殊的信息表达形式&#xff0c;其特征是表达的空间中三个维度的数据。 和二维图像…

【Java程序员面试专栏 算法思维】三 高频面试算法题:搜索算法

一轮的算法训练完成后,对相关的题目有了一个初步理解了,接下来进行专题训练,以下这些题目就是汇总的高频题目,本篇主要聊聊搜索算法,以岛屿问题为切入点练习,所以放到一篇Blog中集中练习 题目关键字解题思路时间空间岛屿数量网格搜索分别向上下左右四个方向探索,遇到海…

【Oracle】玩转Oracle数据库(五):PL/SQL编程

前言 嗨&#xff0c;各位数据库达人&#xff01;准备好迎接数据库编程的新挑战了吗&#xff1f;今天我们要探索的是Oracle数据库中的神秘魔法——PL/SQL编程&#xff01;&#x1f52e;&#x1f4bb; 在这篇博文【Oracle】玩转Oracle数据库&#xff08;五&#xff09;&#xff1…

【数据结构和算法初阶(c语言)】数据结构前言,初识数据结构(给你一个选择学习数据结构和算法的理由)

1.何为数据结构 数据结构(Data Structure)是计算机存储、组织数据的方式&#xff0c;指相互之间存在一种或多种特定关系的 数据元素的集合。本质来讲就是在内存中去管理数据方式比如我们的增删查改。在内存中管理数据的方式有很多种&#xff08;比如数组结构、链式结构、树型结…

导图解文 从梦想到财富(43)只要会请客吃饭,你就能设计出好产品

系列文章说明&#xff1a; 本系列文章 主要是 使用 ​​​​​​​思维导图 对知乎 上一个知乎上的专题系列文章《从梦想到财富》的 一个解读。 1 文章链接 本章节 对应 《从梦想到财富》专栏的 文章链接为&#xff1a;只要会请客吃饭&#xff0c;你就能设计出好产品 2 导图…

CSS 的块级元素和行内元素

CSS 的块级元素和行内元素 常见的块级元素&#xff1a;h1 - h6&#xff0c;p&#xff0c;div&#xff0c; ul&#xff0c; ol&#xff0c; li等 常见的行内元素&#xff1a;a&#xff0c;strong&#xff0c;b&#xff0c;em&#xff0c;i&#xff0c;span等 块级元素的特点 独…

深入理解计算机系统——进程,虚拟内存,文件

文章目录 操作系统之进程线程虚拟内存文件 操作系统之进程 进程是计算机中的程序关于某数据集合上的一次运行活动&#xff0c;是系统进行资源分配的基本单位&#xff0c;是操作系统结构的基础。进程具有以下特征&#xff1a; 独立性。进程是独立运行的单位&#xff0c;具有自…

Camunda7.18流程引擎启动出现Table ‘camunda_platform_docker.ACT_GE_PROPERTY‘的解决方案

文章目录 1、问题描述2、原因分析3、解决方案3.1、方案一&#xff1a;降低mysql版本3.2、方案二&#xff1a;增加nullCatalogMeansCurrent参数&#xff08;推荐&#xff09; 4、总结 1、问题描述 需要在docker中&#xff0c;部署Camunda流程引擎。通过启动脚本camunda-platfor…

Linux系统添加新的网卡,并启用

在Rocky Linux系统中添加新的网卡并启用&#xff0c;一般涉及到以下步骤&#xff1a; 物理连接网卡&#xff1a; 首先确保你的虚拟机已经正确连接了新的网络适配器。 查看新添加的网卡&#xff1a; 在终端中输入以下命令来列出所有已识别的网络接口&#xff1a; ip link show …

1110. 删点成林

1110. 删点成林 关键要点 通过O(1)时间复杂度确认节点是否需要删除 Set to_deleteSet new HashSet<>(); Arrays.stream(to_delete).forEach(to_deleteSet::add); 使用深度优先搜索&#xff08;DFS&#xff09;遍历树 node.left dfs(node.left, s, ans); node.right …