简介
Jmeter是Apache的开源项目,基于Java开发,主要用于进行压力测试。
优点:开源免费、支持多协议、轻量级、功能强盛
官网:https://jmeter.apache.org/index.html
安装
安装步骤:
- 下载:进入jmeter的官网,进入Download页面,因为是基于Java开发的,以是不分平台,下载二进制文件即可,
- 解压安装包
- 修改设置文件:这是为了处置惩罚可能出现的中文乱码问题,在bin目录下打开jmeter.properties,将sampleresult.default.encoding的值改为UTF-8
- 设置环境变量
- 启动jmeter:进入bin目录,在Windows平台下,点击 jmeter.bat文件,启动jmeter
- 修改语言为中文:点击 Options - choose language - Chinese(Simplified)
用户界面:
修改语言:
性能测试和相关指标
jmeter主要是用于做性能测试的,以是这里了解一下性能测试的相关指标
测试的分类:测试可以简朴地分为功能测试和性能测试两种,还有自动化测试,不过它更多是一种测试技巧。
功能测试:测试单个接口的功能
- 单元测试:是程序员来操作的,测试程序中的单个单元
- 冒烟测试:测试程序最基本的功能是否正常
- 回归测试:修改了旧代码后,重新进行测试以确认修改没有引入新的错误或导致其他代码产生错误。
性能测试:
- 基准测试:单用户测试,测试环境确定后,对业务模子中的紧张业务做单独的测试,获取单用户运行时的各项性能指标。在某个时刻,通过基准测试,创建一个已知的性能基准线,当系统的软硬件环境发生变化之后再进行一次基准测试,以确定变化对性能的影响
- 负载测试:通过徐徐增加系统负载,确定在满足系统的性能指标环境下,找出系统可以或许承受的最大负载量的测试
- 稳定性测试:在服务器稳定运行的环境下,进行长时间测试,并终极保证服务器能满足线上业务需求。
- 并发测试:在极短的时间内,发送多个请求,来验证服务器对并发的处置惩罚本领
- 压力测试:在强负载下的测试,查看系统在峰值环境下,是否功能隐患、系统是否具有精良的容错本领和可规复本领
- 性能测试:通过特定的方式对被测试系统按照一定测试策略施加压力,获取该系统的相应时间、TPS、吞吐量、资源使用率等性能指标,来检测系统上线后能否满足用户需求的过程。
自动化测试:编写测试脚本,通过逻辑控制器和关联等功能,测试一系列接口的功能。
性能测试的相关指标:
- QPS:Queries Per Second,每秒查询率,一台服务器每秒钟可以或许实行的查询次数,代表了最大吞吐量
- TPS:Transactions Per Second,吞吐量,每秒事务数,一个事务指客户端发送请求而且接收到相应的过程,客户机在发送请求时开始计时,收到服务器相应后结束计时,以此来计算使用的时间和完成的事务个数。
- 并发数:指系统同时能处置惩罚的请求数量,同时反应了系统的负载本领。这个数值可以分析呆板1秒内的访问日志数量来得到
衡量网站的性能指标
- 相应时间:从开始发送请求到接收到相应所耗费的时间
- 并发数:系统同时能处置惩罚的请求数量
- 并发毗连数:每秒钟服务器毗连的总TCP数量
- 请求数:Query Per Second,每秒多少请求
- 事务数:TPS,每秒事务数
- 并发用户数:单元时间内有多少用户
- 吞吐量:单元时间内系统能处置惩罚的请求数量
大型互联网项目架构目标
- 高性能:提供快速的访问体验
- 高可用:网站服务一直可以正常访问
- 可伸缩:通过增加硬件,来提升处置惩罚本领
- 可扩展:模块间的耦合度低,
- 安全性:网站可以或许承受住外部攻击
性能测试的两件事情:模拟巨大负载、天生测试陈诉
入门案例
在这里,通过一个入门案例来了解jmeter的基本使用。
准备工作
编写一个springboot项目,作为本次测试的目标。
pom.xml:
- <groupId>org.example</groupId>
- <artifactId>learn_jmeter</artifactId>
- <version>1.0-SNAPSHOT</version>
- <properties>
- <maven.compiler.source>8</maven.compiler.source>
- <maven.compiler.target>8</maven.compiler.target>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
- <!--springboot工程需要继承的父工程-->
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.1.8.RELEASE</version>
- <relativePath />
- </parent>
- <dependencies>
- <!--web开发的起步依赖-->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- </dependencies>
复制代码 控制器:
- @RestController
- @RequestMapping("/hello")
- public class HelloController {
- private static final Logger LOG = LoggerFactory.getLogger(HelloController.class);
- private static int i = 1;
- @GetMapping("/h1")
- public String s1() {
- LOG.info("第 {} 次请求", i++);
- return "success";
- }
- }
复制代码 开始测试
jmeter中的两个基本概念:
- 测试计划:jmeter中全部的测试内容都要放在测试计划之下
- 线程组:一个线程就代表一个用户。
设置测试计划:
- 在测试计划内添加线程组:右击测试计划,点击 添加 - 线程(用户) - 线程组,线程组用于发起请求,设置线程组可以设定发起请求的次数。
- 线程组内添加取样器:右击线程组 - 添加 - 取样器 - HTTP请求,将之前准备好的接口的相关信息填写进去。取样器表示发起什么样的请求,在这里选择发起http请求。
- 线程组内添加查看效果树:右测试计划 - 添加 - 监听器 - 查看效果树,不需要设置查看效果树
开始测试:点击左上角菜单栏中的运行按钮,开启测试,点击查看效果树,可以看到每个请求的统计数据
生存测试计划:点击 文件 - 生存,测试计划会被生存为jmx文件,下次直接从文件中打开即可。现实上开始测试的时候,jmeter就会提示用户生存测试计划。
springboot中接收到的请求:
总结:
- jmeter中全部的测试内容都需要放到测试计划中
- 线程组是测试计划的基本单元,线程组的一个线程代表一个用户,可以设置线程数和每个线程的循环次数,也就是用户实行几次操作
- 每一个测试计划都必须有一个取样器和监听器:取样器用于发送请求而且接收相应,监听器用于查看效果,http请求组件是一个取样器,查看效果数树组件是一个监听器
查看性能测试的相关效果
之前的测试流程,只是简朴地使用jmeter发送了一个http请求,而且可以查看效果,接下来,使用jmeter来做压力测试,而且查看压力测试的相关效果指标。
第一步:设置线程组:线程数设置为10个,循环100次
第二步:添加监听器 - 聚合陈诉,这是最简朴的监听器,可以查看性能测试的相关指标。
第三步:开始测试。
第四步:查看效果
效果分析:
- Label:采样器的名称,比方HTTP请求的Name;
- 样本:发送请求的数量
- 平均值:平均相应时间(单元:ms);默认是单个Request的平均相应时间,当使用了Transaction Controller时,也可以以Transaction为单元显示平均相应时间;
- 中位数:50%的用户相应时间小于这个值;
- 95%百分位:95%的用户相应时间小于这个值;
- 99%百分位:99%的用户相应时间小于这个值;
- 最小值:用户相应时间最小值;
- 最大值:用户相应时间最大值;
- 非常%:测试出现的错误请求数量百分比;请求的错误率 = 错误请求的数量/请求的总数;若出现错误就要看服务端的日志查找定位原因;
- 吞吐量:Throughput简称TPS,吞吐量,默认环境下表示每秒处置惩罚的请求数,也就是指服务器处置惩罚本领,TPS越高阐明服务器处置惩罚本领越好;
- KB/sec:每秒从服务器端接收到的数据量;
jmeter中的核心概念
测试计划和线程组
测试计划:存放全部的测试内容,相当于一个项目标根目录
线程组:对于线程进行分类,线程组是测试计划的基本单元,线程组中的每一个线程都代表一个用户
- 线程组的属性
- 名称
- 注释
- 在取样器错误后要实行的动作:默认选择继续,还有启动下一历程循环、停止线程、停止测试
- 线程数
- Ramp-Up时间:准备时长,设置的线程数需要多长时间全部启动。如果线程数为10,准备时长为2,那么需要2秒钟启动10个线程,也就是每秒钟启动5个线程。
- 循环次数:1个线程实行几次
- 延迟创建线程直到需要
- 调度器
- 连续时间:如果循环次数是永久,连续时间会被应用,表示连续多少秒后线程结束
- 启动延迟:线程在几秒之后启动
- 线程组的实行顺序
- 并发实行:多个线程同时实行,默认是并发实行
- 顺序实行:多个线程顺序实行,在最顶层的测试计划界面,勾选独立运行每个线程组,就可以开启顺序实行
- 特殊的线程组
- setUp线程组:最优先实行的线程组,创建方式也是 右击 实行计划,点击 添加 - 线程(用户)- setUp线程组
- tearDown线程组:最后实行的线程组,创建方式类似于setUp线程组
组件和元件
组件:实现单独的某个功能,有取样器、监听器等。
元件:多个类似功能组件的容器。元件也可以理解为组件的一种,下面把它们统称为组件
jmeter中的组件
在之前的入门案例中,打仗了取样器和监听器,它们是jmeter中发送请求和分析相应的基本组件,jmeter还提供了许多别的组件,支持把一系列的请求组合起来,模拟用户的举动。
jmeter中的基本组件:
- 取样器:向服务器发送请求并接收相应的最小单元,jmeter支持差异的取样器,通过这些取样器,jmeter可以支持多种协议,常用的取样器有HTTP取样器、JDBC取样器、FTP取样器
- 监听器:对测试效果进行处置惩罚和可视化展示的一系列组件,常用的监听器有查看效果树、聚合陈诉
用于加强取样器的组件:
- 设置元件:设置别的组件的相关信息,常见的设置元件:HTTP信息头管理器、CSV数据设置、用户自定义变量
- 逻辑控制器:控制取样器实行顺序的组件,常用的逻辑控制器:if控制器、foreach控制器、循环控制器
- 定时器:在操作之前设置等待时间,常见的定时器:同步定时器、常量和吞吐量定时器
- 前置处置惩罚器:用于取样器实行之前对请求进行处置惩罚
- 后置处置惩罚器:用于取样器实行之后对得到的相应进行处置惩罚,常见的后置处置惩罚器:JSON提取器、正则表达式提取器、Xpath提取器
用于加强监听器的组件:
- 断言:对相应效果进行判定,场景的断言组件:相应断言、大小断言、JSON断言、
组件的作用域:组件可以被设置到测试计划下,也可以被设置到线程组下,被设置到那里,作用域就是那里。
组件的实行顺序
- 同一作用域下差异组件实行顺序:设置元件 --> 前置处置惩罚器 --> 定时器 --> 取样器 --> 后置处置惩罚器 --> 断言 --> 监听器
- 同一作用域下雷同组件的实行顺序:从上到下依次实行
使用案例
在这里,通过现实的需求来学习jmeter中的常用组件
需求1:为HTTP请求添加请求头
这个需求需要使用http信息头管理器来完成。
http信息头管理器:设置元件的一种,设置HTTP协议的请求头
- 作用域:如果位于测试计划目录内,作用于测试计划下的全部线程组,如果位于线程组内,作用于线程组
案例:
需求2:把多个http请求的雷同信息提取出来,集中管理
实现这个功能,需要使用“http请求默认值”组件
http请求默认值:设置元件的一种,作用是管理多个http请求的雷同信息。
- 使用步骤:把多个http请求的雷同信息写入到当前组件中,然后,在同一个测试计划下,新创建的HTTP请求就不再需要填写公共信息
案例:
需求3:把多处使用到的数据提取为变量,集中管理
这个需求使用“用户自定义变量”来实现。
用户自定义变量:设置元件的一种,在当前组件中设置键值对,在别的地方,使用 ${变量名} 的方式来引用变量
- 优点:通过用户自定义变量,来实现参数化。参数化是指动态地获取、设置或天生数据,是一种由程序驱动代替人工驱动的数据计划方案,提高脚本的编写服从和编写质量
案例:
需求4:发送10个请求,要求每个请求都有自己独立的数据
实现这个功能,需要从csv文件中读取数据,这需要使用“CSV 数据文件设置”
CSV数据文件设置:设置元件的一种,用户如果想要把数据放到csv文件中,需要使用当前组件。
- 使用方式:设置csv文件的文件名、文件编码、字段名称、分隔符,然后线程每实行一次,就会去csv文件中读取一行数据,用户再使用 ${变量名} 来引用csv文件中的数据。
- 优点:通过从csv文件中读取数据,把测试数据和测试脚本分离,使得测试用例更加灵活,而且可以实现参数化
案例:
注意:
- 编写csv文件:文件中不能有表头,第一行就是数据,字段之间以逗号分割,文件使用utf-8编码。也可以使用txt文件来代替,因为csv文件自己就是普通的文本文件
- csv文件的局限性:字段中不能出现分隔符,使用反斜杠转义也不可以
- 设置线程的运行次数:线程运行一次,读取jmeter中的一行数据,下一次运行时读取下一行,以是运行次数最好和csv文件中的行数相对应,
使用csv文件时线程组的设置方式
在上面的案例中,需要把csv文件中的行数和线程的运行次数对应起来,才华保证线程正好能读取完csv文件中的数据,但是如许在现实使用过程中会很麻烦,以是现在提供一种方式,使得线程组可以在读取完csv文件后自动结束。
设置方式:
- 第一步:在线程组界面:设置线程的循环次数为永久
- 第二步:在CSV数据文件设置界面:
- 设置”遇到文件结束符再次循环“为false,表示只读取一次;
- 设置”遇到文件结束符停止线程“ 为true,因为之前已经设置了线程的循环次数为永久,以是在这里,当csv文件被读取完时,线程就会停止循环
案例:
需求5:判定请求效果是否精确
这个需要需要使用“断言”来实现。
断言:用于判定请求效果的组件。断言和取样器类似,它们是平级关系,断言功能包罗一系列组件,每个组件都可以实行差异范例的断言,包括JSON断言、大小断言等
案例:设置一个json断言,判定返回值中code字段的值是200.
需求6:获取上一个请求返回的数据
需求:用户乐成登录后,服务器会返回一个token,用户使用这个token,可以查看当前用户的具体信息。
实现这个需求,需要使用后置处置惩罚器下的JSON提取器。
后置处置惩罚器:在请求完成之后对相应效果进行处置惩罚。
案例:在这里使用后置处置惩罚器中的JSON提取器,提取服务端返回的json数据,把数据放到变量中,然后在下一个请求中引用变量。
第一步:设置请求的后置处置惩罚器,需要在取样器节点下添加后置处置惩罚器,只有如许后置处置惩罚器才华作用于取样器
第二步:在第二个请求中引用后置处置惩罚器中的变量
需求7:如果上一个请求不精确,下一个请求不实行
需求:用户登录乐成后会返回一个token,在这里需要判定,如果用户没有登录乐成,那么就不实行下一个请求。
实现这个功能,需要使用逻辑控制器。
逻辑控制器:控制它内部全部取样器的实行流程,取样器需要是逻辑控制器的子节点,然后才华生效。
案例:在这里选择使用逻辑控制器中的IF控制器来实现这个功能,将下一个请求放到IF控制器之中。
注意,要取消勾选Interpret选项,在案例中使用到的变量是上一个节点的JSON提取器中提取出来的。
需求8:上传文件
需求:使用jmeter的http取样器,发奉上传文件的请求
实现这个需求,需要使用http取样器中的“文件上传”tab,输入文件名、http请求中文件对应的参数即可。
案例:
需求9:后置处置惩罚器之正则表达式
需求:在http请求的相应中,会返回一个url,现在需要解析出这个url中的路径信息。
实现这个需求,需要使用后置处置惩罚器中的正则表达式提取器,设置正则表达式,提取数据中的内容
案例:
案例讲解:
- 第一步:设置需要从相应的哪部分中提取数据
- 第二步:设置提取出的数据存储到哪个变量中
- 第三步:设置正则表达式,要注意,提取的数据是正则表达式中被括号包裹的数据,相当于分组匹配,在这里的正则表达式是https?://[^/]+(/[^?]+),这个正则表达式用于提取url中的路径部分
- 第四步:模板,表示提取正则表达式中第几个分组的数据,在这里是$1$,表示提取正则表达式中第一个括号中的数据。
扩展:提取正则表达式中的最后一节路径:https?://[^/]+/?.*/([^?]+)
需求10:if控制器 判定变量是10的倍数
在if控制器中写上表达式:${__jexl3(${pageNo} % 10 == 0)},在这里,pageNo就是变量
需求11:循环控制器和计数器
循环控制器是逻辑控制器的一种,计数器是设置元件的一种,团结使用,可以有for循环的效果,但是要注意,计数器必须放在循环控制器中才会在循环控制器的范围内生效。
需求12:跨线程共享变量
实现这个需求的步骤:
- 第一步:添加一个后置处置惩罚器,叫做BeanShell,在内里写入代码:${__setProperty(var, ${var})},在这里,var是要被跨线程共享的变量
- 第二步:在别的线程中引用当前变量:${__P(var)}
原理:在jmeter中,变量是线程共享的,属性是全局共享的,这里把变量设置为一个属性了。
需求13:每两秒钟发送一次请求
使用 定时器 - 固定定时器来做
需求14:从json中提取出一个数组然后遍历这个数组
实现这个需求的步骤:
- 第一步:设置一个JSON提取器,难点在与JSON提取器中路径的设置,这里提供一个案例:$.data
- .avatar,表示提取data中全部名为avatar的变量,而且注意Match No输入-1,表示提取全部变量。
- 第二步:设置ForEach控制器,有几个输入性:
- 变量前缀:JSON提取器中设置的变量,
- 开始循环字段:0
- 结束循环字段:${__javaScript(${变量名_matchNr})},这是jmeter提供的变量
- 输出变量名称:forEach控制器输出的变量名称
- 第三步:在ForEach控制器的内部使用变量。
别的常用组件
定时器:可以实现时间模式相关的性能测试。
- 同步定时器:Synchronized Timer,用来保证取样器在同一时刻向服务器发起负载
- 常量吞吐量定时器:高频率的访问服务器,1s钟访问多少次,连续多少秒,
取样器:
- 数据库取样器:直连数据库,向数据库发送请求并接收相应
在命令行运行脚本
Jmeter有两种运行模式:
- GUI模式:主要用来编写和调试测试脚本
- 命令行模式:对负载机的资源消耗会更小,用来实现高并发和压力测试
在命令行实行测试脚本:jmeter -n -t ${scriptFile} -l ${logFile} -e -o ${dir}
- 参数讲解
- -n 无图形化运行
- -t 被运行的脚本
- -l 将运行信息写入日志文件
- -e 天生测试陈诉
- -o 指定陈诉输出目录
案例:jmeter -n -t blog-api_最热文章.jmx -l j.log -e -o output,在output目录下可以查看jmeter生产的html文件。
- D:\apache-jmeter-5.5>jmeter -n -t blog-api_最热文章.jmx -l j.log -e -o output
- Creating summariser <summary>
- Created the tree successfully using blog-api_.jmx
- Starting standalone test @ April 6, 2024 4:41:58 PM CST (1712392918522)
- Waiting for possible Shutdown/StopTestNow/HeapDump/ThreadDump message on port 4445
- summary + 121 in 00:00:01 = 101.8/s Avg: 53 Min: 10 Max: 155 Err: 0 (0.00%) Active: 10 Started: 10 Finished: 0
- summary + 879 in 00:00:04 = 201.7/s Avg: 47 Min: 6 Max: 127 Err: 0 (0.00%) Active: 0 Started: 10 Finished: 10
- summary = 1000 in 00:00:06 = 180.2/s Avg: 47 Min: 6 Max: 155 Err: 0 (0.00%)
- Tidying up ... @ April 6, 2024 4:42:04 PM CST (1712392924365)
- ... end of run
复制代码 性能测试效果报表:html文件
message on port 4445
summary + 121 in 00:00:01 = 101.8/s Avg: 53 Min: 10 Max: 155 Err: 0 (0.00%) Active: 10 Started: 10 Finished: 0
summary + 879 in 00:00:04 = 201.7/s Avg: 47 Min: 6 Max: 127 Err: 0 (0.00%) Active: 0 Started: 10 Finished: 10
summary = 1000 in 00:00:06 = 180.2/s Avg: 47 Min: 6 Max: 155 Err: 0 (0.00%)
Tidying up … @ April 6, 2024 4:42:04 PM CST (1712392924365)
… end of run
- 性能测试结果报表:html文件
- [外链图片转存中...(img-Qb2zCm3f-1743754695159)]
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |