如何搭建JMeter分布式集群环境来进行性能测试
在本文中,我将介绍如何通过使用虚拟机来搭建一个 JMeter 分布式集群来进行性能测试,并使用命令行工具生成报告。阅读完本文后,你将了解:
- JMeter 分布式模式的架构;
- 如何设置集群环境并进行配置;
- 如何在非 GUI 模式下运行测试并生成报告;
前提条件
在开始之前,请确保满足以下前提条件:
- 确保 JMeter 能够访问待测试的服务器(可以通过虚拟机上的
curl
命令来检查连通性),如果无法访问,你可能需要调研当前环境是否能够用来作为压力源; - 确保所有系统上使用相同版本的 JMeter(我们当前使用的是 5.6.3)。混用不同版本可能无法正常工作;
- 确保系统上的防火墙已禁用或正确打开了相关端口;
概念
控制节点: 运行 jmeter-client 的系统,它控制测试。该系统可以是你的笔记本电脑(需要先打开防火墙)或虚拟机。
工作节点: 运行 jmeter-server 的系统,它接收来自 jmeter-client 的指令并向目标系统发送请求,通常是虚拟机。
目标: 我们计划进行压力测试的 Web 服务器。
image.png安装
对于 MacOS
使用 Homebrew 安装 JMeter,并通过 jmeter --version
命令验证安装:
brew install jmeter
jmeter --version
在我编写本文时,使用的版本是 5.6.3。
对于 Ubuntu20
不要 使用 apt install jmeter
命令安装 JMeter,因为 apt 安装的版本已过时(2.13),加载 .jmx 文件将会报错从而无法正常工作。
手动安装:
- 在 VM 上安装 JDK:
sudo apt install openjdk-11-jre-headless`
-
从 https://jmeter.apache.org/download_jmeter.cgi 下载压缩包文件(通过你的 笔记本电脑),然后将其上传至 VM。
-
使用
scp/rsync
上传至虚拟机,然后解压最新的 JMeter 压缩包。在笔记本电脑上输入以下命令(请记得修改目标目录):
rsync -avz apache-jmeter-5.6.3/ <remote-host>:/path/to/place
- 将文件移动至正确位置并修改 PATH 环境变量:
# 移动至合适的目录,比如 /opt/jmeter
sudo mv /path/to/place /opt/
# 将其添加到 PATH,你可以将其写入 ~/.bashrc 文件以持久化配置
vim ~/.bashrc
export PATH=/opt/jmeter/bin:$PATH
# 退出 vim 并使用 source 命令生效
source ~/.bashrc
- 检查版本,确保一切就绪:
jmeter --version
输出结果应如下所示:
_ ____ _ ____ _ _ _____ _ __ __ _____ _____ _____ ____
/ \ | _ \ / \ / ___| | | | ____| | | \/ | ____|_ _| ____| _ \
/ _ \ | |_) / _ \| | | |_| | _| _ | | |\/| | _| | | | _| | |_) |
/ ___ \| __/ ___ \ |___| _ | |___ | |_| | | | | |___ | | | |___| _ <
/_/ \_\_| /_/ \_\____|_| |_|_____| \___/|_| |_|_____| |_| |_____|_| \_\ 5.6.3
Copyright (c) 1999-2024 The Apache Software Foundation
配置
在运行分布式模式之前,需要完成以下配置:
在控制节点
将服务器 IP 添加到客户端的 Properties 文件中
在 $JMETER_HOME/bin/jmeter.properties
文件中(本文的路径是 /opt/jmeter/bin/jmeter.properties
),找到名为 "remote_hosts" 的单元,添加正在运行的 JMeter 服务器的 IP 地址。可以添加多个服务器,用逗号分隔,例如:
# Edit the line: remote_hosts=127.0.0.1 and configure as below:
remote_hosts=10.0.0.1,10.0.0.2,10.0.0.3
通过更改值并取消注释来禁用 rmi.ssl
:
server.rmi.ssl.disable=true
同时,强烈建议将默认的 jmeter.reportgenerator.overall_granularity
值从 60 秒更改为 5 秒,以获得更好的报告体验!
jmeter.reportgenerator.overall_granularity=5000
否则,你的报告可能就会长成这样:
image.png
更改此值后,上述的报告将更易读:
image.png
在工作节点
通过更改值并取消注释来禁用 rmi.ssl
:
server.rmi.ssl.disable=true
然后启动 jmeter-server 以监听来自控制节点的命令:
jmeter-server
你应看到如下输出:
$ jmeter-server
WARN StatusConsoleListener The use of package scanning to locate plugins is deprecated and will be removed in a future release WARN StatusConsoleListener The use of package scanning to locate plugins is deprecated and will be removed in a future release WARN StatusConsoleListener The use of package scanning to locate plugins is deprecated and will be removed in a future release WARN StatusConsoleListener The use of package scanning to locate plugins is deprecated and will be removed in a future release Created remote object: UnicastServerRef2 [liveRef: [endpoint:[10.0.0.1:38803](local),objID:[-7d9e7ab6:1916e54ddb2:-7fff, -6565134591293374723]]]
使用方式
单节点模式
使用单节点模式进行调试,命令如下:
jmeter -n -t <script_path> -l <results-file>
选项
-n
:以非 GUI 模式运行 JMeter
选项-t
:要运行的 JMeter 测试(.jmx)文件
选项-l
:指定结果日志文件
分布式模式
注意:
所有服务器将运行相同的测试计划。JMeter 不会在服务器之间分配负载,每台服务器都会运行完整的测试计划。因此,如果你设置 1000 个线程并有 6 台 JMeter 服务器,你最终将注入 6000 个线程。
如果 jmeter.properties
文件配置正确,只需在执行命令时添加 -r
选项,例如:
jmeter -n -t <script_path> -l <results-file> -r
选项
-r
: 使用remote_hosts
属性中指定的所有节点。
你还可以使用 -R
选项指定希望使用的节点,例如:
jmeter -n -t <script_path> -l <results-file> -R 10.0.0.1,10.0.0.2
此时只有 10.0.0.1
和 10.0.0.2
会参与测试,输出将如下所示:
$ jmeter -n -t demo.jmx -l result.csv -r
WARN StatusConsoleListener The use of package scanning to locate plugins is deprecated and will be removed in a future release
WARN StatusConsoleListener The use of package scanning to locate plugins is deprecated and will be removed in a future release
WARN StatusConsoleListener The use of package scanning to locate plugins is deprecated and will be removed in a future release
WARN StatusConsoleListener The use of package scanning to locate plugins is deprecated and will be removed in a future release
Creating summariser <summary>
Created the tree successfully using demo.jmx
Configuring remote engine: 10.0.0.1
Configuring remote engine: 10.0.0.2
Starting distributed test with remote engines: [10.0.0.1, 10.0.0.2] @ 2024 Aug 20 14:11:02 CST (1724134262441)
Warning: Nashorn engine is planned to be removed from a future JDK release
Remote engines have been started:[10.0.0.1, 10.0.0.2]
Waiting for possible Shutdown/StopTestNow/HeapDump/ThreadDump message on port 4445
summary + 1 in 00:00:00 = 17.2/s Avg: 1 Min: 1 Max: 1 Err: 0 (0.00%) Active: 2 Started: 2 Finished: 0
summary + 5999 in 00:00:10 = 605.8/s Avg: 0 Min: 0 Max: 3 Err: 0 (0.00%) Active: 0 Started: 200 Finished: 200
summary = 6000 in 00:00:10 = 602.2/s Avg: 0 Min: 0 Max: 3 Err: 0 (0.00%)
Tidying up remote @ 2024 Aug 20 14:11:12 CST (1724134272743)
… end of run
HTML 报告生成
要从现有结果文件生成报告,使用以下命令:
jmeter -g <result-file> -o <Path to output folder>
或者在负载测试完成后立即生成报告,使用以下命令:
jmeter -n -t <script_path> -l <result-file> -r -e -o <Path to output folder>
假设你运行以下命令:
jmeter -n -t demo.jmx -l result.csv -r -e -o report
然后你将看到如下输出:
$ ll ./report/
total 32
drwxr-xr-x 4 dohong users 4096 Aug 20 14:44 ./
drwx------ 10 dohong users 4096 Aug 20 14:44 ../
drwxr-xr-x 5 dohong users 4096 Aug 20 14:44 content/
-rw-r--r-- 1 dohong users 9669 Aug 20 14:44 index.html
drwxr-xr-x 5 dohong users 4096 Aug 20 14:44 sbadmin2-1.0.7/
-rw-r--r-- 1 dohong users 890 Aug 20 14:44 statistics.json
双击打开 index.html
文件你就会得到类似如下的报告:
左侧导航栏可以切换不同的页面查看不同的统计数据和图表,至此,分布式压测的环境搭建就全部大功告成了。
注意事项
- 将
jmeter.reportgenerator.overall_granularity
的值从 60000 改为 5000 强烈建议,这可以带来更好的报告体验。 - 无需手动同步测试脚本到工作节点,JMeter 会为你完成同步,但仍需要将本地脚本同步到控制节点;
- 使用 CLI 模式 而非 GUI 模式,避免性能下降;
- 使用尽可能少的监听器;如果使用 -l 标志记录结果,监听器可以删除或禁用。
- 在负载测试过程中不要使用 "查看结果树" 或 "查看表格中的结果" 监听器,它们应仅在脚本调试阶段使用,否则性能可能会下降 3 倍!
- 如果测试需要大量数据,尤其是随机化或加密/解密数据,请将测试数据提前生成并通过 CSV 数据集读取文件,这可以避免运行时浪费资源。