jmeter压力测试动态修改并发参数

https://blog.csdn.net/weixin_45131345/article/details/117412808#:~:text=%E4%B8%BA%E4%BA%86%E6%8C%89%E6%8C%87%E5%AE%9A%E6%97%B6%E9%95%BF%E6%89%A7%E8%A1%8C%EF%BC%8C%E9%9C%80%E8%A6%81%E5%B0%86%E6%89%A7%E8%A1%8C%E6%AC%A1%E6%95%B0%E8%AE%BE%E7%BD%AE%E4%B8%BA%20Forever%20%E3%80%82%20%E5%9C%A8%20JMeter%20%E5%86%85%E9%83%A8%E5%AE%9E%E7%8E%B0%E4%B8%AD%EF%BC%8C%E6%89%A7%E8%A1%8C%E6%AC%A1%E6%95%B0%E4%B8%BA%20-1%20%E5%8D%B3%E8%A1%A8%E7%A4%BA,%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%A6%82%E4%B8%8B%EF%BC%9A%20jmeter%20-n%20-t%20test.jmx%20-Jload.concurrency%3D50%20-Jload.duration%3D120%20-Jload.count%3D-1

Apache JMeter 是 Apache 旗下的开源压测工具,创建于 1999 年初,迄今已有超过 20 年历史。JMeter 功能丰富,社区(用户群体)庞大,是主流开源压测工具之一。

性能测试通常集中在新系统上线或大型活动前(如电商大促,春节活动等),以验证系统能力,帮助排查定位性能瓶颈等问题。

一次压测活动可粗略分为几个步骤:

场景配置。配置压测场景模拟用户(业务)与系统的交互。
压测执行。按指定压力量级启动压测。
压测监控分析。压测中通常关注施压 RPS,成功率,业务响应时间(RT),网络带宽等关键指标。
报告总结。披露系统能力是否符合要求,同时沉淀记录系统性能演变和优化过程。
下面我们讨论如何使用 JMeter 完成上述步骤,及相关的最佳实践建议。

JMeter 使用 Java 开发,需要先安装 JDK 并配置好 PATH 环境变量,然后从官网下载 JMeter 二进制压缩包解压即可。
建议将 JMeter bin 目录也添加到 PATH 环境变量,这样在命令行下输入 jmeter 命令即可启动 JMeter 。

场景配置
简单 HTTP 请求配置
最常见的压测场景即 HTTP 压测。
压测场景在 JMeter 脚本中叫做 Test Plan(压测计划),打开 JMeter 默认即为一个空 Test Plan 。JMeter 使用并发(线程)数控制压力大小,一个线程可看做一个执行请求的虚拟用户。在 Test Plan 上点击右键,添加一个 Thread Group(线程组)。

 

 

线程组默认为 1 个线程并只执行一次 1 次,这很方便测试执行脚本,保持此默认值即可。

 

 

JMeter 中发送请求的组件叫做 Sampler(采样器)。在 Thread Group 上单击右键,添加一个 HTTP Request 节点(采样器)。

 

 

HTTP 请求最关键的配置即 URL,JMeter 允许将 URL 协议类型(Protocol)、服务器名、请求路径(Path)等拆开单独配置。也可以直接将整个 URL(如 JMeter 主页 http://jmeter.apache.org/ )填写到 Path,其他字段保留为空即可。这样,一个最简单的 HTTP 压测脚本就配置好了。

 

 

为了方便测试、调试脚本,可在 Test Plan 下添加一个 View Results Tree 监听器(Listener)。这个监听器仅用于编辑脚本时测试、调试脚本,查看请求执行详情,不需要做任何配置。

 

 

测试执行脚本
第一次执行脚本前,需要先保存脚本,如保存为 test.jmx 。以后每次执行脚本前,JMeter 默认会自动保存脚本。

连续多次执行脚本时,JMeter 默认不会清理历史记录。为了避免历史执行结果干扰,可先点击 Clear All 按钮手动清空历史记录,再点击 Start 按钮执行脚本,这样看到的执行结果更清爽,方便排查问题。

 

 

按照默认线程组配置,脚本执行一次即结束。点击 View Results Tree ,可看到请求执行详细信息,包括请求头,请求体,响应头和完整的响应体等信息。

 

 

场景编排
真实压测场景通常不会只有一个请求,而是多个请求按一定顺序和规则的编排组合,即场景编排。场景编排是 JMeter 等压测引擎最重要的功能之一,也是与 apache ab等简单压测工具的重要区别之一。

这里我们假设一个最简单的场景,先访问 JMeter 主页,停留 1 秒钟后跳转到下载页。

一个脚本访问一个网站的不同页面(Path)时,可添加一个 HTTP Request Defaults 节点,配置默认协议类型和服务器名。这样可避免重复配置,需要修改协议类型(如 https 与 http 切换)或压测域名时,只用修改 HTTP Request Defaults 即可。

 

 

HTTP Request Defaults 配置服务器名为 jmeter.apache.org(协议类型默认为 http),鼠标可拖动 HTTP Request Defaults 节点移动到 HTTP 请求节点之前。

 

 

每个请求节点可设置一个具有业务含义的名字,方便理解和管理。访问 JMeter 主页的 HTTP 请求可改名为 home ,同时 Path 修改为 / 。再添加一个 HTTP 请求节点,命名为 download page ,设置 Path 为 /download_jmeter.cgi 即可。

 

 

模拟在 home 页面停顿 1 秒钟。home 节点上右键,添加一个 Constant Timer 子节点,设置延迟时间为 1000 毫秒即可。

 

 

再次执行脚本,点击 View Results Tree 可看到两个 HTTP 请求节点的执行详情。

 

 

注意:

Timer 节点作为场景编排辅助节点,没有请求执行动作,也没有执行详情显示。
循环执行脚本时,最后一个节点 download page 执行结束后,会立即跳转到脚本开头,执行第一个节点 home 。
可在 download page 上也添加一个 Timer,模拟停留一秒之后再继续后续请求。

JMeter 的压测执行
编辑、调试脚本时,我们通常设置为 1 个线程并且只执行 1 次。执行压力测试时,通常需要以较高的压力持续执行一段时间。

脚本固定配置压力
如计划以 50 并发执行 2 分钟,可修改脚本 Thread Group 配置如下。

 

 

配置说明:

并发数(Number of Threads (users))设置为 50 。
循环次数(Loop Count)勾选永远执行(Forever)。
勾选 Scheduler,设置执行时长(Duration (seconds))为 120 秒。
通常我们在 JMeter 图形界面(GUI)编辑脚本,但执行压力测试时 GUI 占用额外资源可能影响施压性能,而且施压机可能没有图形界面环境(如 ssh 远程登录施压机)。因此脚本编辑完成后,通常以命令行模式执行 JMeter 压力测试。

进入 JMeter 脚本目录,执行 JMeter 压力测试的命令为:

jmeter -n -t <脚本>
如执行上述 test.jmx 脚本,命令如下:

jmeter -n -t test.jmx
输出结果如下:

Creating summariser <summary>
Created the tree successfully using test.jmx
Starting the test @ Tue Jun 25 14:38:32 CST 2019 (1561444712414)
Waiting for possible Shutdown/StopTestNow/Heapdump message on port 4445
summary + 553 in 00:00:27 = 20.3/s Avg: 1378 Min: 252 Max: 8587 Err: 0 (0.00%) Active: 50 Started: 50 Finished: 0
summary + 882 in 00:00:30 = 29.4/s Avg: 685 Min: 222 Max: 4272 Err: 0 (0.00%) Active: 50 Started: 50 Finished: 0
summary = 1435 in 00:00:57 = 25.1/s Avg: 952 Min: 222 Max: 8587 Err: 0 (0.00%)
summary + 829 in 00:00:30 = 27.5/s Avg: 815 Min: 222 Max: 21310 Err: 0 (0.00%) Active: 50 Started: 50 Finished: 0
summary = 2264 in 00:01:27 = 25.9/s Avg: 902 Min: 222 Max: 21310 Err: 0 (0.00%)
summary + 881 in 00:00:30 = 29.5/s Avg: 700 Min: 221 Max: 3896 Err: 0 (0.00%) Active: 50 Started: 50 Finished: 0
summary = 3145 in 00:01:57 = 26.8/s Avg: 845 Min: 221 Max: 21310 Err: 0 (0.00%)
summary + 127 in 00:00:05 = 24.2/s Avg: 797 Min: 224 Max: 3819 Err: 0 (0.00%) Active: 0 Started: 50 Finished: 50
summary = 3272 in 00:02:02 = 26.7/s Avg: 843 Min: 221 Max: 21310 Err: 0 (0.00%)
Tidying up ... @ Tue Jun 25 14:40:35 CST 2019 (1561444835251)
... end of run
压测过程中默认每 30 秒输出一次统计数据,2 分钟后(实际为 00:02:02,比预设的 2 分钟多出少许误差)压测结束。看最后一行统计数据,平均 RPS(每秒请求数)为 26.7,平均 RT (响应时间)为 843 毫秒。

尝试核对一下统计数据。脚本包含两个请求,每个请求附加 1 秒钟等待时间,发送一个请求平均耗时为 RT 843 毫秒 + 等待 1000 毫秒。单线程理论 RPS 为 1000.0 / (843 + 1000),总共 50 个线程,全场景理论 RPS 为 1000.0 / (843 + 1000) * 50 = 27.13,与统计值 26.7 有一定误差。这是因为除了请求 RT 和等待时间,脚本执行请求之间还可能存在少量时间消耗。

命令行动态设置压力
实际工作中,常常需要以不同的压力大小反复执行压力测试,在脚本中写死压力大小(并发数)和执行时间显然很不方便。

如何动态指定压力大小呢,这里有一个技巧。JMeter 脚本支持使用 JMeter 属性进行配置,JMeter 命令行支持使用 -J 参数动态指定 JMeter 属性。把这两者结合起来,即可实现在命令行通过 -J 参数动态设置压力大小。

修改 JMeter 脚本使用 JMeter 属性配置压力大小,配置如下:

 

 

配置说明:

并发数配置为 ${__P(load.concurrency,1)},循环次数取消勾选 Forever,配置为 ${__P(load.count,1)}。 未设置对应的 JMeter 属性时,默认为 1 ,满足只执行 1 次以测试、调试脚本的需求。
执行时长配置为 ${__P(load.duration,60)},默认 1 分钟(60 秒)。
测试命令行直接执行脚本:

jmeter -n -t test.jmx
可看到统计输出如下:

summary = 2 in 00:00:03 = 0.6/s Avg: 485 Min: 408 Max: 563 Err: 0 (0.00%)
默认一个并发并且只执行一次,发出 2 个请求(脚本循环一次发出两个请求),约 3 秒后脚本停止。
注意:默认执行时间是 1 分钟,同时配置了循环次数和执行时间时,有一个条件先满足脚本即停止。

为了按指定时长执行,需要将执行次数设置为 Forever 。
在 JMeter 内部实现中,执行次数为 -1 即表示 Forever 。
指定以 50 并发执行 2 分钟,jmeter 命令行如下:

jmeter -n -t test.jmx -Jload.concurrency=50 -Jload.duration=120 -Jload.count=-1
执行结果与前述脚本固定配置 50 并发的结果类似。

posted @ 2023-01-31 16:12  Ootori  阅读(1433)  评论(0编辑  收藏  举报