【软件测试】学习笔记-构建并执行 JMeter 脚本的正确姿势
有些团队在组建之初往往并没有配置性能测试人员,后来随着公司业务体量的上升,开始有了性能测试的需求,很多公司为了节约成本会在业务测试团队里选一些技术能力不错的同学进行性能测试,但这些同学也是摸着石头过河。他们会去网上寻找一些做性能的方案,通常的步骤是写脚本,出结果然后交给开发。这虽然能够依葫芦画瓢地完成一些性能测试的内容,但整个过程中会存在不少值得商榷之处。
这篇文章就以脚本为切入点,探讨在脚本构建与执行过程中可能存在不规范的地方有哪些,以及如何去解决。
脚本构建
脚本构建就是编写脚本,是你正式开始执行性能测试的第一步,对于常规的请求来说只需要通过界面的指引就可以完成,这个是非常容易的,但是上手容易不代表你使用方法科学,下面我带你看看常见的误区。
一个线程组、一条链路走到底
先来看下这样一张线程组的图:

图 1:一个线程组
图中包含了注册、登录、浏览商品、查看订单等,它们在同一个线程组,基于同一线程依次进行业务。这样的做法其实和自动化非常相似。
比如张三先注册一个网站,然后进行登录、添加购物车等操作。但仔细想一想,对于一个网站的性能而言,这么考虑是有些问题的。
在正常情况下,基于同一个时间节点,一部分人在浏览商品,而另一部分人在下单。这两部分之间没有先后关系,人数占比也不一定就是 1:1。脚本中的设计思路实际上也是你对性能测试模型的理解,能够反馈出模型中的用户访问比例分布,这块内容我会在第二模块重点描述,不仅会讲述满足脚本的跑通,还会通过脚本构建基于性能模型的场景。
未提取公共部分,增加脚本管理难度
我在平时的工作中发现,有的测试会基于同一类型的 HTTP 请求,配置相同的 host、端口等,并没有很好地利用JMeter 中作用域的思想。
一般全链路级别的测试脚本里可能会包含上百个接口,对于一些 host 和端口号,并不需要每一个接口都去配置,我们可以使用一个 HTTP 请求默认值去做公共部分。如果说不提取这些公共部分,每改动一个配置,所有接口可能都要改动,这样脚本维护成本工作量也会比较大,有可能会造成“牵一发而动全身”的情况。
查看结果树使用频率高
在脚本调试过程中,我们通常会添加结果树来实时查看返回数据的正确性。这个插件本身是比较消耗性能的,在正式压测中应当禁止使用。一般来说,在脚本调试中通过作用域的思想去配置一个查看结果树就可以了,不要过度使用,不然等到正式压测的时候,一个个地禁用结果树不仅会消耗时间,还容易遗漏。
脚本逻辑复杂
有的测试在编写脚本的过程中为了区分业务逻辑,会使用很多插件,比如 if 判断、循环, 这些插件虽然可以让你进入不同的业务场景,但会增加脚本的复杂度,影响发起压力的效率。你可以自己做一些对比测试,看使用该插件和去除该插件实际的处理能力相差多少,不要因为自己的脚本结构而影响实际的性能测试结果。
以上是在脚本构建时,一些普遍存在的误区,而规范的脚本构建,我认为要做到真实和精简。
- 真实在于你的脚本可以体现出真实的用户访问场景;
- 精简在于少使用周边的插件,比如通过 JMeter 去监控服务器资源,这样的监控不仅简单粗糙,而且较大地影响 JMeter 的压力发起的效率。
脚本执行
在正确构建了脚本之后,我们就要来看如何执行脚本了。脚本执行就是你怎么去运行脚本,可能有的同学会一头雾水,我直接点击界面上的运行按钮不就行了吗?事实上真正的压测可不是这个样子的。
界面化执行性能测试
一些测试人员在 Windows 或 Mac 环境编写完脚本后,会直接用界面化的方式进行性能测试,这样的做法是非常不规范的。打开 JMeter 界面之后就会弹出提示,如图 2 所示:

图 2:界面化性能测试提示
很多人会选择直接忽略掉,但图中的第一段是这样的:
Don’t use GUI mode for load testing!only for Test creation and Test debugging。For load testing,use NON GUI Mode。
中文意思就是图形化模式只让你调试,不要进行压测。
图形化的压测方式会消耗较多的客户端性能,在压测过程中容易因为客户端问题导致内存溢出。既然官方不推荐我们使用图形化界面,那我们应当如何执行测试脚本呢?
我们来看图 2 中的第三行内容:
jmeter -n -t [jmx file] -l [results file] -e -o [Path to web report folder]
官方早已给出答案:通过命令行执行。命令行执行的方式同样适用于 Windows、Mac 和 Linux 系统,不需要纠结系统兼容性的问题。
那既然命令行执行的方式不会造成这样的问题,为什么还要用界面化的方式呢?
相对于命令行执行,界面化的方式更为简单、方便,但命令行执行也并不是完美无缺的。
我们来回顾这段文字中的含义:
jmeter -n -t [jmx file] -l [results file] -e -o [Path to web report folder]
- -n 表示在非 GUI 模式下运行 JMeter;
- -t 表示要运行的 JMeter 测试脚本文件,一般是 jmx 结尾的文件;
- -l 表示记录结果的文件,默认以 jtl 结尾;
- -e 表示测试完成后生成测试报表;
- -o 表示指定的生成结果文件夹位置。
我们来看一下执行了上面的脚本后的实际效果,如图 3 所示:
![]()
图 3:脚本执行后的效果
从图中可以看到,命令行的方式直接产生了总的 TPS、报错和一些时间层级的指标。命令行的执行方式规避了一些图形化界面存在的问题,但这样的结果输出方式存在 2 个问题:
- 看不到实时的接口返回报错的具体信息;
- 看不到混合场景下的每个接口的实时处理能力。
这 2 个问题都有个关键词是“实时”,是在压测过程中容易遗漏的点。虽然压测之后我们有很多方式可以回溯,但在性能测试过程中,发现、排查、诊断问题是必不可少的环节,它能够帮助我们以最快的速度发现问题的线索,让问题迅速得到解决。
先来看第一点:看不到实时的接口返回报错的具体信息。
jmeter.log 刚刚执行过程中记录了哪些内容呢?如图 4 所示:
![]()
图 4:jmeter.log 执行时记录的内容
你可以看到只能显示报错率,但看不到具体的报错内容,那如何去解决呢?一般我会使用 beanshell,把判定为报错的内容增加到 log 里。beanshell 的示意代码如下所示,你可以根据自己的需求改进。
String response = prev.getResponseDataAsString();//获取接口响应信息String code = prev.getResponseCode();//获取接口响应状态码if (code.equals("200")){//根据返回状态码判断log.info("Respnse is " + response);//打印正确的返回信息,建议调试使用避免无谓的性能消耗}else {log.error("Error Response is"+response);//打印错误的返回信息}
这样就会自动在 jmeter.log 中打印出具体的报错信息,如图 5 所示:
图 5:报错信息
客户端的日志只是我们需要关注的点之一,排查错误的根因还需要结合服务端的报错日志,一般来说服务端的报错日志都有相关的平台记录和查询,比较原始的方式也可以根据服务器的路径找相关日志。
我们再来看第二个问题:看不到综合场景下的每个接口的实时处理能力。
我个人认为原生的实时查看结果是有些鸡肋的,如果想实时且直观地看到每个接口的处理能力,我比较推荐 JMeter+InfluxDB+Grafana 的方式,基本流程如下图所示:

图 6:JMeter+InfluxDB+Grafana
JMeter 的二次开发可以满足很多定制化的需求,但也比较考验开发的能力。如果不想进行二次开发,JMeter+InfluxDB+Grafana 也是一种比较好的实现方式了。
下面,对 InfluxDB 和 Grafana 做一个简单的介绍,包括特点、安装等。
InfluxDB
InfluxDB 是 Go 语言编写的时间序列数据库,用于处理海量写入与负载查询。涉及大量时间戳数据的任何用例(包括 DevOps 监控、应用程序指标等)。我认为 InfluxDB 最大的特点在于可以按照时间序列面对海量数据时候的高性能读写能力,非常适合在性能测试场景下用作数据存储。
安装
首先带你来看下 InfluxDB 具体的安装步骤(基于 CentOS 7.0),直接输入以下命令行即可:
#wget https://dl.influxdata.com/influxdb/releases/influxdb-1.1.0.x86_64.rpm#rpm -ivh Influxdb-1.1.0.x86_64.rpm#systemctl enable Influxdb#systemctl start Influxdb#systemctl status Influxdb (查看 Influxdb 状态)
基本操作
当你已经安装完成之后,我带你了解下如何操作 InfluxDB:
#influx linux 命令行模式下进入数据库#show databases
查看库
create database jmeter;
建库
use jmeter
使用该库
show measurements;
查看库下面的表
InfluxDB 成功安装并且建库之后,我们就可以来配置 JMeter 脚本了。配置过程可以分为以下 3 步。
(1)添加核心插件,在 listener 组件中选择 Backend Listener(如下图所示)。

图 7:添加 Backkend Listenner
(2)Backend Listener implementation 中选择第二项(如下图所示)。

图 8:Backend Listener implementation
(3)配置 InfluxDB URL,示例“http://127.0.0.1:8086/write?db=jmeter”;IP 为实际 InfluxDB 地址的 IP,DB 的值是 InfluxDB 中创建的库名字(如下图所示)。

图 9:配置连接 influxdb 库的具体信息
配置完后运行 JMeter 脚本,再去 InfluxDB 的 JMeter 数据库中查看是否有数据,有数据则代表如上链路配置没有问题。
再来了解一下 Grafana。
Grafana
Grafana 是一个跨平台的开源的度量分析和可视化工具,纯 JavaScript 开发的前端工具,通过访问库(如 InfluxDB),展示自定义报表、显示图表等。大多时候用在时序数据的监控上。Grafana 功能强大、UI 灵活,并且提供了丰富的插件。
安装步骤
在 linux 命令行下直接输入以下内容即可:
#wget https://dl.grafana.com/oss/release/grafana-6.4.4-1.x86_64.rpm#下载 granafa#yum install Grafana-6.4.4-1.x86_64.rpm#安装,遇到需要输入的直接 y 就 ok;#systemctl start Grafana-server#systemctl enable Grafana-server#启动 Grafana#/etc/Grafana/Grafana.ini配置文件路径,一般保持默认配置即可。#systemctl status firewalld.service查看防火墙状态,防止出现其他干扰问题,最好关闭登录访问 Grafana 访问:http://127.0.1.1:3000(ip 自行替换,3000 为默认端口)默认账号/密码:admin/admin
输入密码后如果出现了如下界面,说明 Grafana 安装成功了。

图 10:Grafana 界面
数据源配置
为什么要配置数据源呢,简单来说就是 Grafana 需要获取数据去展示,数据源的配置就是告诉你去哪里找数据,配置安装的 InfluxDB 地址和端口号,如下图所示:

图 11:配置地址和端口号
然后输入 InfluxDB 中写入的数据库名字,如下图所示:

图 12:数据库名字
输入完成之后可以 Save & Test,如出现以下示意图即配置成功:

图 13:配置成功
导入 JMeter 模板
为了达到更好的展示效果,Grafana 官网提供了针对性的展示模版。先下载 JMeter 模板,然后再导入 Grafana。

图 14:导入 JMeter 模板
配置完成后,运行 JMeter 脚本。如果在界面右上方下拉选择 5s,则每 5s 更新一次:

图 15:运行 JMeter 脚本
如上图便是完成了实时压测情况下运行结果的实时展示图,你可以以此为基础,进行多接口的数据采集,相应增加脚本里的 Backend Listener 插件,区分不同的 application name 名称,你会看到不同的接口数据都进入 influxdb 数据库中。并且 Grafana 从 Edit 中进入, 你可以根据不同的 application name 修改 SQL 来区分展示。

图 16:编辑 Grafana
总结
这一篇主要介绍了构建和执行性能测试脚本时的一些注意事项,总结了目前业内使用 JMeter 常见的方法。你不仅需要知道这些常见的手段,也需要知道为什么要这么做,这么做有什么好处,同样随着实际采集数据指标的增高,这些做法可能还会存在哪些缺陷或者注意点,如果上述内容你都能考虑清楚了,相信你也就掌握工具了。
相关文章:
【软件测试】学习笔记-构建并执行 JMeter 脚本的正确姿势
有些团队在组建之初往往并没有配置性能测试人员,后来随着公司业务体量的上升,开始有了性能测试的需求,很多公司为了节约成本会在业务测试团队里选一些技术能力不错的同学进行性能测试,但这些同学也是摸着石头过河。他们会去网上寻…...
iOS 面试 Swift基础题
一、Swift 存储属性和计算属性比较: 存储型属性:用于存储一个常量或者变量 计算型属性: 计算性属性不直接存储值,而是用 get / set 来取值 和 赋值,可以操作其他属性的变化. 计算属性可以用于类、结构体和枚举,存储属性只能用于类和结构体。存储属性可…...
(七)for循环控制
文章目录 用法while的用法for的用法两者之间的联系可以相互等价用for改写while示例for和while的死循环怎么写for循环见怪不怪表达式1省略第一.三个表达式省略(for 改 while)全省略即死循环(上面已介绍) 用法 类比学习while语句 …...
ASP .NET Core Api 使用过滤器
过滤器说明 过滤器与中间件很相似,过滤器(Filters)可在管道(pipeline)特定阶段(particular stage)前后执行操作。可以将过滤器视为拦截器(interceptors)。 过滤器级别范围…...
CodeGPT--(Visual )
GitCode - 开发者的代码家园 gitcode.com/ inscode.csdn.net/liujiaping/java_1706242128563/edit?openFileMain.java&editTypelite marketplace.visualstudio.com/items?itemNameCSDN.csdn-codegpt&spm1018.2226.3001.9836&extra%5Butm_source%5Dvip_chatgpt_c…...
1.Mybatis入门
目录 前言 1入门 1.1 入门程序实现 1.2 数据准备 编辑 1.3 配置Mybatis 1.4 编写SQL语句 1.5 单元测试 1.6 解决SQL警告与提示 2. JDBC介绍(了解) 2.1 介绍 2.2 代码 2.3 问题分析 2.4 技术对比 3. 数据库连接池 3.1 介绍 3.2 产品 4. lombok 4.1 介绍 4.…...
android camera系列(Camera1、Camera2、CameraX)的使用以及输出的图像格式
一、Camera 1.1、结合SurfaceView实现预览 1.1.1、布局 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-au…...
live555搭建流式rtsp服务器
源代码已上传gitee 一、需求 live555源代码中的liveMediaServer是将本地文件作为源文件搭建rtsp服务器,我想用live555封装一个第三方库,接收流数据搭建Rtsp服务器;预想接口如下: class LiveRtspServer { public:/***brief构造一…...
Apache孵化器领路人与导师的职责
对于捐赠到 ASF 孵化器的项目来说, ASF 孵化器项目管理委员会(IPMC)的成员会扮演两个角色,一个 孵化器领路人(Champion),另外一个是孵化器导师(Mentor)。 本文源自 ALC …...
【C++中STL】set/multiset容器
set/multiset容器 Set基本概念set构造和赋值set的大小和交换set的插入和删除set查找和统计 set和multiset的区别pair对组两种创建方式 set容器排序 Set基本概念 所有元素都会在插入时自动被排序。 set/multist容器属于关联式容器,底层结构属于二叉树。 set不允许容…...
使用 create-react-app 创建 react 应用
一、创建项目并启动 第一步:全局安装:npm install -g create-react-app 第二步:切换到想创建项目的目录,使用命令create-react-app hello-react 第三步:进入项目目录,cd hello-react 第四步:启…...
obs-studio 源码学习 obs.h
obs.h 引用头文件介绍 c99defs.h:这个头文件提供了一些 C99 标准的定义和声明,包括一些常用的宏定义和类型定义,用于提高代码的可移植性和兼容性。 bmem.h:这个头文件提供了对内存分配和管理的功能,包括一些内存分配…...
C语言-指针的基本知识(上)
一、关于内存 存储器:存储数据器件 外存 外存又叫外部存储器,长期存放数据,掉电不丢失数据 常见的外存设备:硬盘、flash、rom、u盘、光盘、磁带 内存 内存又叫内部存储器,暂时存放数据,掉电数据…...
4核16G幻兽帕鲁服务器优惠价格表,阿里云和腾讯云报价
幻兽帕鲁服务器价格多少钱?4核16G服务器Palworld官方推荐配置,阿里云4核16G服务器32元1个月、96元3个月,腾讯云幻兽帕鲁服务器服务器4核16G14M带宽66元一个月、277元3个月,8核32G22M配置115元1个月、345元3个月,16核64…...
GitHub 上传文件夹到远程仓库、再次上传修改文件、如何使用lfs上传大文件、github报错一些问题
按照大家的做法,把自己遇到的问题及解决方案写出来(注意:Error里面有些方法有时候我用可以成功,有时候我用也不能成功,写出来仅供参考,实在不行重头再clone,add,commit,p…...
一些es的基本操作
目录 给索引增加字段:给索引删除字段[^1]:创建索引:插入document删除document(应该是按ID) : 给索引增加字段: 用postMan: 给名为population_portrait_hash_seven的索引增加了一个text类型的字段。 用chrome插件Elasticvue 的Re…...
酒鬼酒2024年展望:稳发展动能,迈入恢复性增长轨道
文 | 琥珀酒研社 作者 | 渡过 最近几个月来,白酒估值回落到近十年来低位,反映出了整个白酒行业的市场低迷和虚弱现状。不管是头部企业五粮液、泸州老窖,还是区域酒企口子窖、金种子酒等,最近都通过“回购”或“增持”࿰…...
1002. HarmonyOS 开发问题:鸿蒙 OS 技术特性是什么?
1002. HarmonyOS 开发问题:鸿蒙 OS 技术特性是什么? 硬件互助,资源共享 分布式软总线 分布式软总线是多种终端设备的统一基座,为设备之间的互联互通提供了统一的分布式通信能力,能够快速发现并连接设备,高效地分发…...
vue-cli 无法安装问题解决
在macOS上安装vue-cli,但一直都失败,最后终于解决。 先后报错了2个问题。 报错无法安装 其实原因是源被切断,默认的源是官方的,但在CN是无法正常访问,各种问题。直接将源修改才可以。但可能需要试多次。 npm config…...
spring-bus消息总线的使用
文章目录 依赖bus应用接口用到的封装参数类 接收的应用监听器定义的事件类 使用bus定义bus远程调用A应用数据更新后通过bus数据同步给B应用 依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bus-amqp…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...
Python常用模块:time、os、shutil与flask初探
一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...
怎么开发一个网络协议模块(C语言框架)之(六) ——通用对象池总结(核心)
+---------------------------+ | operEntryTbl[] | ← 操作对象池 (对象数组) +---------------------------+ | 0 | 1 | 2 | ... | N-1 | +---------------------------+↓ 初始化时全部加入 +------------------------+ +-------------------------+ | …...
