Jmeter从下载到完成性能测试实战教程(Windows平台)

前言

本教程内容庞大,所以尽量写的精简,没有写出脚本的具体编写步骤,有兴趣的朋友可以下载Demo后和教程对照着看。
请求的服务端,是通过服务端模拟器来生成的。可以下载Mock服务端模拟器,设定与教程相同的请求地址来学习。
Demo下载地址:点击下载
Mock服务端模拟器:点击下载

下载安装Jmeter

计算机上已装好Jmeter的请跳过此步骤。本教程是根据Jmeter5.0编写的,其他版本可能有出入。

  1. 访问官网并下载,培养大家自己动手的习惯,就不给出官网链接了,自己百度吧。
    Binaries的意思是发行版。Source是源码,用于二次开发。

在这里插入图片描述

  1. 解压出来就算装好了。

在这里插入图片描述

  1. 配置环境变量(计算机右键->属性->高级系统设置->环境变量)
    新建一个环境变量 变量名JMETER_HOME 变量值:你解压出来的目录
    编辑Path变量 追加一段内容;%JMETER_HOME%\bin

在这里插入图片描述

安装相关插件

下载插件管理工具

  1. 百度一下jmeter plugins找到Jmeter插件官网,下载plugins-manager.jar(插件管理工具)

在这里插入图片描述

  1. 下载好了之后,放进Jmeter安装路径的/lib/ext目录下,再重启Jmeter

在这里插入图片描述

安装性能测试相关插件

  1. 打开插件管理工具 (选项->Plugins Manager->Available Plugins)

在这里插入图片描述

  1. 根据需求勾选以下插件:
插件名 -
Custom Thread Groups - 个人觉得最好用的性能测试线程组
3 Basic Graphs - 活动线程数变化曲线
- - 响应时间变化曲线
- - 每秒事务处理率(TPS)
Composite Timeline Graph - 把多个图形监听器组合起来
PerfMon (Servers Performance Monitoring) - 远程监听服务器资源使用率
Command-Line Graph Plotting Tool - 可以手动把jtl或csv文件转化成图片(主要用于PerfMon结果生成图形)

*以上插件都是按需勾选,譬如你的服务器是放在阿里云上的,自带了资源监控,就不需要PerfMon插件了。

安装监控服务器资源程序

  1. PerfMon还需要额外的一个程序:ServerAgent 它的功能是获取当前计算机的CPU、RAM、I/O等使用情况
    我们在插件中找到,访问它的介绍页面

在这里插入图片描述

  1. 往下拉,在Installation中点击here,进入下载页面

在这里插入图片描述

  1. 点击下载最新版。

在这里插入图片描述

  1. 这是一个独立程序,它需要放到服务器上运行,然后测试过程中监听服务器的资源使用情况。
    *建议本地也放一份,这个后面会用到。

在这里插入图片描述

  1. 再次强调,这个程序是应该放在被测对象机器上的。
    *这里用于演示,请求的是127.0.0.1的地址,所以就在本机运行了。实际工作中客户机和服务器肯定是分开的。

在这里插入图片描述

设计一个性能测试脚本

性能测试场景

  1. 用户定义变量配置元件,可以设置一些环境变量,让我们快速切换测试环境。

在这里插入图片描述

  1. 我喜欢再定义一个HTTP请求默认值配置元件,因为这样之后的Sampler就不用再写协议、IP和端口号了

在这里插入图片描述

  1. Concurrency Thread Group 最好用的性能测试场景线程组
    Target Concurrency是 总线程数
    Ramp Up Time(min) 是 总运行时间(单位分钟)
    Ramp-Up Steps Count 是份数
    Hold Target Rate Time(min)是保持执行时间
    实际意义就是,总共启动500个线程,执行5分钟,分成10个阶段启动,最后持续0分钟结束。

在这里插入图片描述

性能测试监听器

  1. 每秒活动线程变化,基本和设置的场景一致

在这里插入图片描述

  1. 每秒响应时间变化

在这里插入图片描述

  1. 每秒事务处理率(TPS)

在这里插入图片描述

  1. 组合图形
    结合以上3个监听器我们可以看出,随着活动线程数的不断增加,响应时间越来越高,但TPS保持稳定没有太大变化。

在这里插入图片描述

  1. 服务端CPU和RAM
    这里因为测试对象也在本地,所以写的localhost,实际应该填写运行ServerAgent的服务端地址。

在这里插入图片描述

  1. 硬盘I/O和网络I/O
    建议和CPU分开来监听,因为CPU和RAM峰值100,而I/O峰值数百万。放在一起看起来不方便。

在这里插入图片描述

  1. 如果你需要使用PerfMon监听器,那么建议你在测试计划中定义一个脚本路径地址的变量。__P()函数用来用cmd接收参数。然后在PerfMon监听器中,使用这个路径,把监听结果保存成文件。这样配置后,我们通过非GUI模式运行脚本时,可以把服务器资源使用情况转化成图表。

在这里插入图片描述

编写启动器

  1. 根据我长期以来经验,并不断完善,我建议可以参考我写的批处理脚本
  • 生成当前日志 是为了多次测试结果不覆盖,并保留归档
  • 配置地址 jmxPath是为了把PerfMon监听器结果保存,否则直接用.就能获取到当前路径了。
    jmeterPath也是为了把PerfMon监听器的结果转化成图表图片。
  • 创建日期文件夹 用于存放测试结果
  • 执行Jmeter
  • 生成监听器截图 (*Jmeter5.0必须要安装"Command-Line Graph Plotting Tool"插件,才能用这个命令)
  • 日志存档 把JMeter.log文件放入日期文件夹。创建Release文件夹,用于保存最新测试结果。

在这里插入图片描述

@echo off

rem 生成当前日期
set date=%date:~0,4%%date:~5,2%%date:~8,2%
if "%time:~0,2%" lss "10" (set hour=0%time:~1,1%) else (set hour=%time:~0,2%)
set time=%hour%%time:~3,2%%time:~6,2%
set d=%date%%time%
echo 当前日期: %d%

rem 配置地址
set jmxPath="E:\Desktop\博文\Demo"
set jmeterPath="F:\apache-jmeter-5.0"

rem 创建日期文件夹
mkdir %jmxPath%\%d%
if not exist %jmxPath%\%d%\PerfMon mkdir %jmxPath%\%d%\PerfMon >nul

rem 执行Jmeter
call jmeter -JjmxPath="%jmxPath%\%d%" -n -t %jmxPath%\Demo.jmx -l %jmxPath%\%d%\Result.jtl -e -o %jmxPath%\%d%\Report

rem 生成监听器截图(需要修改版本号)
call java -jar %jmeterPath%\lib\cmdrunner-2.2.jar --tool Reporter --generate-png %jmxPath%\%d%\CPUMemory.png --input-jtl %jmxPath%\%d%\PerfMon\CPUMemory.jtl --plugin-type PerfMon
call java -jar %jmeterPath%\lib\cmdrunner-2.2.jar --tool Reporter --generate-png %jmxPath%\%d%\IO.png --input-jtl %jmxPath%\%d%\PerfMon\IO.jtl --plugin-type PerfMon

:: 日志存档
move %jmxPath%\jmeter.log %jmxPath%\%d% >nul
if not exist %jmxPath%\Release mkdir %jmxPath%\Release >nul
xcopy /Y %jmxPath%\%d% %jmxPath%\Release /s /f /h >nul

:: pause
  1. 如果不用PerfMon插件、不需要生成CPU&RAM等资源情况,可以参考这种写法

在这里插入图片描述

@echo off

rem 生成当前日期
set date=%date:~0,4%%date:~5,2%%date:~8,2%
if "%time:~0,2%" lss "10" (set hour=0%time:~1,1%) else (set hour=%time:~0,2%)
set time=%hour%%time:~3,2%%time:~6,2%
set d=%date%%time%
echo 当前日期: %d%

rem 创建日期文件夹
mkdir %d%

rem 执行Jmeter
call jmeter -n -t Demo.jmx -l %d%\Result.jtl -e -o %d%\Report

:: 日志存档
move jmeter.log %d% >nul
if not exist Release mkdir Release >nul
xcopy /Y %d% Release /s /f /h >nul

:: pause
  1. 以上写法是把脚本和测试结果放在一个路径下的。如果要把测试报告放在其他地址下(譬如放到Jenkins上,肯定要测试结果和脚本分离了),可以做相应修改。同时还可以对多余测试报告进行清除。

在这里插入图片描述

@echo off

rem 生成当前日期
set date=%date:~0,4%%date:~5,2%%date:~8,2%
if "%time:~0,2%" lss "10" (set hour=0%time:~1,1%) else (set hour=%time:~0,2%)
set time=%hour%%time:~3,2%%time:~6,2%
set d=%date%%time%
echo 当前日期: %d%

rem 配置地址
set reportPath="E:\Desktop\API_TEST_RESULT"

rem 创建日期文件夹
mkdir %reportPath%\%d%

rem 执行Jmeter
call jmeter -n -t Demo.jmx -l %reportPath%\%d%\Result.jtl -e -o %reportPath%\%d%\Report

:: 日志存档
move jmeter.log %reportPath%\%d% >nul
if not exist %reportPath%\Release mkdir %reportPath%\Release >nul
xcopy /Y %reportPath%\%d% %reportPath%\Release /s /f /h >nul

:: 清除多余历史测试报告
for /f "skip=8 delims=" %%a in ('dir /b /ad /o-d "%reportPath%"\*') do @rd /s /q "%reportPath%"\"%%a" && echo del %%a

:: pause

性能测试过程

执行测试

  1. 有了批处理程序,我们可以快速的调整和反复执行不同场景。
    前面演示为了方便,实际上我们通常把线程组里的参数(总线程数、总时间、切割份数)也用__P()函数来传递。这样我们放到Jenkins服武器上或需要多次执行时,只需要修改.bat中的参数就可以改变执行的场景。

在这里插入图片描述

  1. 执行完之后就会有一个日期文件夹来存放本次测试结果

在这里插入图片描述

  1. 直接把PerfMon中的CPU等信息转化成了图片。

在这里插入图片描述

测试报告

  1. 报表部分有PASS率、平均响应时间、90%响应时间等信息。如果有错误,下方也有错误信息。
    为什么我的报告是中文,你的报告是英文?因为我自己汉化了。
    汉化方法见:https://blog.csdn.net/tomoya_chen/article/details/56481479
    最新完全汉化包:下载页面

在这里插入图片描述

  1. 每秒活动线程变化

在这里插入图片描述

  1. 每秒响应时间变化

在这里插入图片描述

  1. 每秒事务处理率(TPS)

在这里插入图片描述

分析测试结果

  1. 理论

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

  1. 分析

以刚才的测试报告为例,由于测试时间比较短,尾部释放线程阶段不参考。但仍然可以看出一些趋势。

  • 随着用户数越来越多,TPS也越来越高,但是在33分开始趋于平缓。甚至在34分开始,明明活动线程数上升,但TPS反而下降的不合理情况。
  • 34分响应时间变化倒是不太明显,但是在35分开始急剧上升了,此时TPS也是继续下降,活动线程数为500。

如果忽略脚本释放线程的部分,可以得出初步结论,系统最多能支持每秒处理22个事务,即TPS=22,此时对应的用户数在每秒250~300人。更多用户的情况下,系统还不至于崩溃,但响应时间会很慢。

所以,这就是真实结果了吗?不是,我们再来看一下CPU情况。

  • 服务器CPU一直在65%~75%之间,在刚才分析结果的拐点区仍然没有继续升高。这说明服务器并没有太吃力。

什么原因呢?有可能有以下几种情况:

  • 测试机本身机能受限,测试过程中自己都卡的不行了,导致发出到服务器的请求没有那么密集,没有产生那么大的压力。
  • 网络I/O的问题,网络带宽上下行满了,导致响应时间变长,但本身服务器性能空闲。
  • 服务器对请求的IP或终端有特殊处理,限制 了最大TPS。
  • 其他

性能测试易学难精,跑完脚本给开发看固然简单,但自己分析的话需要的知识面非常广,但是响应时间就包含了七八层。我推测本次测试应该是第1种情况,因为NET I/O并不高。还需要加大线程数、延长测试时间继续测试来观察一下,甚至需要用到分布式方法进行测试。第四种情况是之前测试一个WebSocket接口时发现,服务端对单个终端发出的请求会限制TPS。当时我的解决办法是写了一个并发启动脚本,让一台机器跑20个jmeter脚本,8台机器模拟160个终端,最终才测出服务器的TPS在1400多,否则无论怎么测都是20TPS。

  1. 总结

Jmeter在规范了插件管理之后,把活动线程数、响应时间、TPS打包成一个3 Basic Graphs。就是因为日常测试中基本就是靠这3个监听器完成初步分析。而为什么监听服务器资源也很重要呢?Jmeter在规范了插件管理之后,把活动线程数、响应时间、TPS打包成一个3 Basic Graphs。就是因为日常测试中基本就是靠这3个监听器完成初步分析。而为什么监听服务器资源也很重要呢?

因为:
1.我们要验证测试结果是否准确。
2.真的对服务器造成压力了,我们要找到CPU满载的那个时间点。再结合以上3个监听器一起分析。

猜你喜欢

转载自blog.csdn.net/tomoya_chen/article/details/82901291