JMeter 5.5分布式模式下Backend Listener属性读取及自定义实现问题
解决JMeter分布式模式下Backend Listener读取属性失败及自定义监听器问题
一、分布式下Backend Listener无法读取${__P(influxdburl)}的原因
Backend Listener在远程节点初始化阶段就会加载配置参数,若属性文件仅在本地节点配置、远程节点未同步该属性,或者参数解析时机早于属性加载,就会导致读取失败。其他采样器能正常读取,是因为它们在测试运行阶段才解析属性,此时属性已完成同步。
二、无需自定义代码的解决方法(优先推荐)
1. 同步属性文件到所有远程节点
- 将包含
influxdburl=xxx的属性文件(比如user.properties)复制到所有远程节点的JMeterbin目录下,JMeter启动时会自动加载该文件。 - 或者启动远程节点时,通过
-j参数指定属性文件:# Linux/macOS ./jmeter-server -j /path/to/your/properties.properties # Windows jmeter-server.bat -j D:\path\to\your\properties.properties
2. 通过系统参数传递属性
启动本地JMeter和所有远程节点时,统一添加-J参数传递地址:
# 本地启动 jmeter -J influxdburl=myinfluxurl:port/write?db=dbname&p=somevalue -n -t testplan.jmx -r # 远程节点启动(每个节点都要加) jmeter-server -J influxdburl=myinfluxurl:port/write?db=dbname&p=somevalue
此时${__P(influxdburl)}就能在所有节点正常读取。
3. 用JSR223预处理器动态设置参数
在测试计划最顶层添加JSR223 PreProcessor(选择Groovy语言),代码如下:
// 找到测试计划中的Backend Listener def backendListener = ctx.getTestPlan().getTestElementList().find { it.name == "Backend Listener" } if (backendListener) { // 从属性中读取地址并设置 backendListener.setProperty("influxdbUrl", props.get("influxdburl")) }
该代码会在测试启动前,将属性值注入到Backend Listener的参数中。
三、自定义BeanShell Listener代码的问题及改进
你当前的代码存在3个核心问题:
- 新建的
HashTree未关联到当前测试计划的执行树,导致自定义Backend Listener根本不会被执行; - BeanShell Listener是在每个采样器执行后运行,此时再创建Backend Listener已经错过测试初始化时机,无法捕获完整的测试数据;
- 没有将自定义Backend Listener添加到测试计划的监听器集合中。
改进方案:用Setup Thread Group创建自定义监听器
- 添加一个Setup Thread Group(该线程组会在所有测试线程启动前执行一次);
- 在Setup Thread Group中添加JSR223 Sampler(选择Groovy语言),代码如下:
import org.apache.jmeter.visualizers.backend.BackendListener import org.apache.jmeter.config.Arguments import org.apache.jmeter.testelement.TestPlan // 获取当前测试计划 TestPlan testPlan = ctx.getTestPlan() // 创建自定义Backend Listener BackendListener customBackend = new BackendListener() customBackend.setName("Custom InfluxDB Backend Listener") // 配置参数,直接读取属性值 Arguments args = new Arguments() args.addArgument("influxdbMetricsSender", "org.apache.jmeter.visualizers.backend.influxdb.HttpMetricsSender") args.addArgument("influxdbUrl", props.get("influxdburl")) args.addArgument("application", "myapplication") args.addArgument("measurement", "jmeter") args.addArgument("summaryOnly", "false") args.addArgument("samplersRegex", ".*") args.addArgument("percentiles", "90;95;99") args.addArgument("testTitle","mytestname") args.addArgument("eventTags"," ") customBackend.setArguments(args) // 将监听器添加到测试计划 testPlan.addTestElement(customBackend)
这段代码会在测试启动前,将自定义Backend Listener注册到测试计划中,从而正常捕获并发送测试数据到InfluxDB。
内容的提问来源于stack exchange,提问作者JMeterLearner
相关产品推荐
相关产品推荐

