ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

JMeter属性配置详解:从加载优先级到乱码、分布式与界面问题排查

JMeter属性配置详解:从加载优先级到乱码、分布式与界面问题排查 做接口测试和性能压测JMeter 几乎人手一套。但很多人用了很久还是被各种“小毛病”卡住中文乱码、结果保存不完整、远程压测连不上、界面控件挤成一团、上传文件文件名变成乱码……这些问题的根源往往不是脚本写错而是没搞懂 JMeter 的常用属性是怎么加载、怎么覆盖、怎么生效的。这篇我把自己这些年调 JMeter 属性、改配置的实际经验系统梳理一遍适合刚入门想搞明白底层逻辑的新人也适合已经写过不少脚本但总在环境问题上浪费时间的老手。先说结论JMeter 的属性本质上是一组全局键值对相当于整个工具的“系统设置”。你可以在多个地方定义同一个键但最终生效顺序是有讲究的。理解了这套规则就不会再遇到“改了 jmeter.properties 却不起作用”的怪事。文章里我会拆开讲属性文件的类型和优先级再按实际使用频率梳理编码、结果保存、远程分发、界面显示、数据库连接这几类最常用的属性最后附上一份问题排查速查表。全程用我实际操作过的例子说话配置部分可以直接抄。1. 属性体系与加载优先级1.1 三类属性文件角色与推荐用法JMeter 安装包解压后bin 目录下会有一堆.properties文件跟常用属性关系最密切的主要是三个jmeter.properties全量主配置启动时默认加载。里面注释非常多很多默认值并不需要改。user.properties用户自建或者默认生成的个性化配置文件启动时会被加载到主配置之上。system.properties系统级 Java 属性配置一般很少动。我的建议是凡是需要长期生效的自定义项统一放到user.properties不要直接改jmeter.properties。原因有两点一是jmeter.properties在升级新版时容易被覆盖而你自己的配置放在user.properties里可以跨版本保留二是jmeter.properties文件太大了改错一处排查的时候非常容易眼花。user.properties默认是空的你只管往里面加。比如我固定加在开头的两行就是sampleresult.default.encodingUTF-8 file.encodingUTF-8这两行解决了大部分请求响应中文乱码问题。需要提醒的是改完配置文件不是立刻生效而是要重启 JMeter 才会重新读取属性我见过不少人在改完配置后不重启然后跑来问为什么还乱码其实只是没重启而已。1.2 属性的加载顺序谁说了算属性是可以被多次赋值的JMeter 的加载顺序大致是内置默认值 -jmeter.properties-user.properties- 命令行参数。意思是后加载的覆盖先加载的命令行参数优先级最高。命令行覆盖有两个入口一个是-J参数用于设置 JMeter 属性另一个是-D参数用于设置 JVM 系统属性。比如你临时要跑一轮压测希望结果文件输出格式从 CSV 换成 XML完全不用改配置文件直接敲jmeter -n -t test.jmx -l result.jtl -Jjmeter.save.saveservice.output_formatxml这里的-J就是临时覆盖属性。所以排查“改了没生效”的时候先确认一下你的启动脚本或命令行里是不是也带了相同的键。我在一次远程压测中就因为启动脚本里写死了-Jserver.rmi.port导致配置文件怎么改都没效果最后翻出来一看问题是脚本里的参数优先级更高真的很坑。还有一个隐藏入口是 JMeter 内置的函数__P和__property。脚本里可以通过${__P(sampleresult.default.encoding)}读取当前生效的属性值排查配置时直接在 Debug Sampler 里打出来看比肉眼翻文件快得多。Debug Sampler 是调试 JMeter 脚本时最简单有效的组件很多初学者不知道它能直接输出 JMeter 变量和 JMeter 属性建议常用。1.3 为什么要关心加载优先级一个真实例子刚接触属性优先级时很多人觉得“不就是个覆盖顺序吗背下来不就好了”。但实际排查时你要面对的往往不是优先级本身而是多层配置叠加之后的意外行为。我举一个真实案例。有段时间我帮开发团队调接口压测脚本里需要读取一个从外部传入的服务器地址参数化写的是${__P(server.host,localhost)}。本地跑得好好的上到压测机一跑请求全部打到了 localhost。检查了很久才发现压测机上user.properties里残留了server.hostlocalhost而当天启动命令里漏加了-Jserver.hostxxx于是脚本按低优先级的文件值执行了。这件事之后我养成了一个习惯只要脚本里依赖外部属性启动命令就必须显式传一次-J哪怕值和文件里的默认值一样也不能省。因为“显式声明”本身就是在降低不确定因素。这个例子说明属性优先级不只是理论它直接决定了脚本在不同环境上复现时的行为一致性。你如果不希望某个配置被环境里的遗留值影响就必须用最高优先级的方式把它钉死。2. 高频使用的核心属性详解2.1 编码类属性中文乱码的根中文乱码是 JMeter 初学者遇到的第一个“鬼”其实大部分乱码都出在编码属性没改对。首先HTTP 响应内容的解码默认走的是sampleresult.default.encoding默认值是 ISO-8859-1也就是西欧字符集。返回的接口数据如果是 UTF-8查看结果树里自然是一堆乱码。改成下面这样并重启 JMetersampleresult.default.encodingUTF-8其次如果你在脚本里用 CSV 数据文件做参数化CSV 文件本身是 UTF-8 编码但 JMeter 读取时默认用系统编码Windows 中文系统下很容易出现读出来中文乱码的情况。这时可以在 CSV Data Set Config 里显式设置“文件编码”为 UTF-8也可以在属性里加jmeter.csvfile.encodingUTF-8这个属性是 JMeter 5.x 里专门控制 CSV 文件读取的如果你用的版本比较老优先在组件面板里设置编码。最后还有一个file.encoding它影响 JMeter 读写文件的默认编码属于 JVM 系统属性。如果你在脚本里用 Beanshell 或 JSR223 脚本读文件、写文件遇到乱码可以在启动命令加-Dfile.encodingUTF-8。我用这个参数解决的场景非常典型用 JSR223 脚本把 JSON 提取结果写入到一个本地文件时生成文件里的中文总是变成问号加了-Dfile.encodingUTF-8之后才正常。2.2 结果保存与监听器相关属性压测做完结果保存不下来或者保存下来的 JTL 文件内容不全也是高频问题。这背后主要是一组jmeter.save.saveservice.*属性。默认情况下JMeter 在 GUI 模式运行结束后如果你直接用命令行生成报告可能发现结果文件里缺少请求响应数据、断言结果等关键字段。标准做法是在user.properties里打开你需要保存的字段jmeter.save.saveservice.output_formatcsv jmeter.save.saveservice.response_datatrue jmeter.save.saveservice.request_headerstrue jmeter.save.saveservice.response_headerstrue jmeter.save.saveservice.assertion_resultstrue jmeter.save.saveservice.latencytrue jmeter.save.saveservice.idle_timetrue jmeter.save.saveservice.hostnametrue jmeter.save.saveservice.thread_countstrue我特别强调assertion_results这个字段因为默认情况下断言结果是不落盘的。如果你想知道哪些请求断言失败不看这个字段报告里只能看到错误数看不到具体断言信息。还有response_data默认值可能是 false所以很多人命令行跑完想回看响应打开 JTL 发现响应数据是空的就是这个原因。如果你需要把 JSON 提取出来的字段生成一份单独的结果文件也可以在 JSR223 后置处理器里用vars和props配合把提取结果写进自定义文件。我在后面第 3 节会专门写这个场景。2.3 远程压测与端口属性用 JMeter 做大规模压测一台机器容易遇到性能瓶颈很多人会配置分布式压测也就是 Controller Agent 的模式。这时有两个属性特别关键。第一个是 Agent 端监听端口server.rmi.port1099第二个是本地通信端口很多时候不配置这个分布式会启动失败或者报告生成报错server.rmi.localport1099这里的逻辑是Agent 启动后会建两个 RMI 连接通道一个用于监听 Controller 的连接请求一个用于回传数据。server.rmi.port是主监听端口server.rmi.localport是本地数据通道端口。很多网络环境只放行了 1099没放行其他随机端口就会出现“连接建立了但传输失败”的诡异现象。所以分布式配置时我习惯把两个端口显式设置成同一个固定值同时在防火墙里放行这个端口。另外还有一个属性jmeterengine.nongui.port0这个属性很关键。当 JMeter 以命令行模式启动时它会默认打开一个端口用于远程控制。0表示让系统随机选择但如果遇到多张网卡或者防火墙策略严格随机端口就可能不可达。遇到 Agent 无法启动时报 RMI 相关错误可以先把这个属性设置为固定端口比如jmeterengine.nongui.port5100再重新启动。2.4 界面布局与显示相关属性“jmeter界面布局错乱、窗口控件重叠/撕裂”是 Windows 用户很常见的求助点。JMeter 在 Windows 高分屏、远程桌面、低分辨率环境下容易出现按钮重叠、控件错位、文字和输入框挤在一起的现象。JMeter 4.0 以后引入了高 DPI 支持相关属性有两组放在user.properties里可以救急jmeter.hidpi.modetrue jmeter.hidpi.scale1.5第一行是开启高分辨率缩放支持第二行是设置缩放比例。如果你的屏幕是 1080P 但觉得界面过小可以设成 1.25 或者 1.5如果屏幕是 4K可以考虑 2.0。这里有个容易踩的坑只设置jmeter.hidpi.modetrue不设置 scale 的话某些老旧主题下反而会把控件撑开看起来更乱。所以两行要一起改。如果改了这两个属性界面还是撕裂那就不是 JMeter 配置能解决的了而是 Java 的 2D 渲染和显卡驱动冲突。这时需要修改bin目录下启动脚本里的 JVM 参数。找到jmeter.batWindows或jmeter.shLinux/macOS在 JVM 参数区加一行-Dsun.java2d.d3dfalsed3d是 Direct3D 硬件加速开关禁用后 Java 会走软件渲染界面绘制稳定很多代价是拖动窗口时会略微变慢。这个方案我实测过Windows 远程桌面里出现的控件重叠问题基本能消除。3. 常用属性在真实场景中的实战配置3.1 文件上传中文文件名乱码的完整处理JMeter 模拟文件上传是很常见的需求但中文文件名乱码比普通响应乱码更隐蔽。因为乱码发生在不同的层请求头里的文件名和 HTTP Body 里的文件内容。我处理过的一个场景是用 JMeter 上传一个名叫“测试报告.pdf”的文件后端收到的文件名变成了一串“测试”开头但后半截乱掉的字符。排查和修复流程分三步在user.properties里把file.encodingUTF-8和sampleresult.default.encodingUTF-8都配上重启 JMeter。在 HTTP 请求的“HTTP Header Manager”里手动加上请求头Content-Type: multipart/form-dataAccept: application/jsonX-Requested-With: XMLHttpRequest如果后端仍然拿不到正确的文件名可以在 JSR223 前置处理器里用代码构造 Multipart但这种情况很少。大多数文件上传乱码问题第一步就解决了。注意修改属性后一定要重启 JMeter不能只在当前线程组里反复试。另外 Windows 命令行窗口启动 JMeter 时如果窗口的代码页是 GBK某些版本的 JMeter 会对中文参数再编一次码。建议用jmeter.bat所在目录的快捷方式启动或者把 Windows 控制台代码页切换到 UTF-8。3.2 JSON 提取、BeanShell 断言与属性读写热搜里经常看到“jmeter提取json结果生成文件”和“jmeter beanshell断言”这两组词它们背后其实是一条常用链路接口返回 JSON - 提取字段 - 断言校验 - 把结果写入文件。JSON 提取器本身不涉及属性配置但它提取的值可以放进 JMeter 的变量和属性中。例如我提取登录接口返回的token在“JSON Extractor”里设变量名loginToken默认值设为NOT_FOUND。紧接着用 BeanShell 或 JSR223 断言做校验String token vars.get(loginToken); if (token null || token.equals(NOT_FOUND)) { props.put(login_failure_count, Integer.valueOf(props.get(login_failure_count, 0).toString()) 1); AssertionResult.setFailure(true, token not found); } else { props.put(login_token, token); }这里用到了vars和props两个对象。简单说vars是当前线程组内共享的变量不同线程之间隔离props是 JMeter 全局属性所有线程都能读。把 token 存入props就能跨线程供后续请求引用这就是属性在脚本执行期间最常用的用法。如果要生成 JSON 提取结果文件可以在 JSR223 后置处理器里写File file new File(extracted_data.csv); if (file.length() 0) { file.append(timestamp,token\n); } file.append(System.currentTimeMillis() , vars.get(loginToken) \n);写文件时如果遇到中文乱码就回到 2.1 节说的-Dfile.encodingUTF-8。我不建议在新脚本里继续用 BeanShell因为 BeanShell 语法兼容性和性能都不如 JSR223 Groovy。如果只是维护老脚本BeanShell 能跑就行新写脚本坚持用 JSR223/Groovy。3.3 数据库压测脚本常用属性JMeter 做数据库压测是热搜词里出现频率很高的需求。除了 JDBC Connection Configuration 里的连接串和驱动外真正影响稳定性的是连接串上的属性参数。以 MySQL 为例我常用的数据库连接 URL 是这样的jdbc:mysql://192.168.1.100:3306/test_db?useUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/ShanghairewriteBatchedStatementstrueconnectTimeout5000socketTimeout600000这些参数里useUnicodetrue和characterEncodingUTF-8解决数据库读写中文乱码rewriteBatchedStatementstrue对压测时批量写入性能提升非常明显connectTimeout设置连接超时时间避免数据库假死时请求卡死socketTimeout设置读取超时压测中如果某个慢 SQL 卡住不至于整个线程组都堵住。JMeter 配置文件里和 JDBC 有关的属性不多但有一个很实用jdbc.config.check.querySELECT 1它的作用是定期校验连接是否存活。压测过程中如果数据库主动断开了空闲连接而 JMeter 不知道就会出现“连接已被对端关闭”的报错。设置了这个校验属性JMeter 会在取连接前先发一条查询验证连接可用。这个属性在不同的 JMeter 版本里名称略有差异可以在jmeter.properties里搜索check.query确认没有的话就手动加。3.4 录制 HTTPS 脚本与证书属性录制 HTTPS 脚本是 JMeter 里一个非常常用但很容易卡住的场景。难点不在于 JMeter 本身而在于浏览器不信任 JMeter 的根证书。JMeter 安装目录bin下有一个证书文件ApacheJMeterTemporaryRootCA.crt。录制 HTTPS 脚本前需要把这个证书导入浏览器的“受信任的根证书颁发机构”。导入后浏览器访问 HTTPS 网站时才会放行。和证书相关的属性有两个需要注意proxy.certs.dynamictrue proxy.certs.jdktrueproxy.certs.dynamic控制是否动态生成每个域名的证书副本打开后可以避免部分网站奇怪证书导致录制失败proxy.certs.jdk控制是否使用 JDK 自带的证书逻辑。如果你用的是较新的 JDK 版本且原本能录制的 HTTPS 脚本在某一天突然报证书错误优先检查这两项。这里特别提醒一下录制 HTTPS 时JMeter 会要求你设置一个监听端口浏览器需要把互联网流量转发到这个端口。很多教程会把这一步叫“设置代理”其实你只需要在浏览器网络设置里把 HTTP 和 HTTPS 的监听地址都填成127.0.0.1和端口号就行不会影响你正常的电脑使用。录制完成后记得把浏览器设置还原否则你会发现后续所有网页都打不开。这个操作本身完全在本地机器上完成只涉及本机回环地址不会影响外部网络也没有任何安全风险。4. 常见问题与排查技巧实录4.1 报错“could not delete existing file C:\Windows\System32”是怎么回事有些人在 Windows 上启动 JMeter 时会看到一个很吓人的报错Failed to create ... could not delete existing file C:\Windows\System32或类似提示。这个报错其实不是真的要删除你的系统文件而是 JMeter 在启动时尝试清理某些临时文件或日志文件结果没有权限。排查顺序是确认你是否用管理员权限运行 JMeter。如果不用管理员权限JMeter 写入某些受保护目录时会失败。但我不建议随手就“以管理员身份运行”因为没必要给工具那么高的权限优先做第 2 步。检查日志文件路径是否指向了系统目录。JMeter 的日志路径由属性log_file控制默认在bin目录下的jmeter.log。如果在user.properties或jmeter.properties里把log_file改成了类似C:\Windows\System32\jmeter.log的路径就会触发这个报错。把它改回到一个普通用户目录log_fileC:/Users/你的用户名/jmeter.log如果还不行检查杀毒软件是不是正在占用jmeter.log或临时目录。把 JMeter 目录加入杀毒软件白名单重启后再试。实际上这个报大家遇到的概率不高但一旦遇到会非常慌。先看log_file和临时目录权限比重新安装靠谱得多。4.2 界面控件重叠/撕裂的终极排查界面问题在 2.3 节已经给了一套属性配置。如果改完还不好可以继续向下排查先确认 JMeter 版本。JMeter 5.5 之前的界面缩放实现依赖 JDK 的字体渲染JDK 8 Update 201 之前的分辨率适配确实很差。如果在 Win7 或者老电脑上跑建议优先升级到 JDK 8 最新更新版再配合jmeter.hidpi.scale调整。Win7 用户注意JMeter 5.6 之后对老操作系统支持有变化装新版 JMeter 之前先查一下官方支持矩阵。如果用的是非官方修改版或汉化补丁界面错乱的概率也会增加。有些汉化包直接改写了框架资源文件和标准 JDK 渲染不兼容。我见过最夸张的一个案例是界面控件完全错位最后发现用户装了一个第三方汉化整合包。这种问题没有任何配置能救换回官方原版就好。4.3 安装与环境变量JDK8、Win7 与 apt install热门词里总是重复出现“jmeter安装、jmeter官网下载、win7配置jmeter环境变量、sudo apt install jmeter”。这些安装问题本质上是版本匹配和环境变量。先说版本匹配JMeter 5.x 官方要求 JDK 8 或 JDK 11。JDK 9、10 是过渡版本兼容性不好不建议用。Win7 用户最高能稳定运行的 JDK 8 版本是 8u202因为之后的 JDK 8 官方不再支持 Win7。安装了 JDK 之后配置环境变量需要以下两个值JAVA_HOMEC:\Program Files\Java\jdk1.8.0_202 PATH%JAVA_HOME%\bin;%PATH%配置完成后在命令行执行java -version能看到版本号再执行jmeter.bat就能启动。Linux 用户用sudo apt install jmeter安装的通常是 Debian/Ubuntu 仓库里打包的版本版本往往比较旧而且缺少很多插件。我的建议是不管用什么系统都去 Apache JMeter 官方网站下载最新二进制包不要用系统源里的版本。用旧版本做压测除了功能缺失某些长度较大的响应体还会触发旧版本的性能问题结果可信度会打折扣。下载安装时还有一个很常见的问题JMeter 启动需要能区分 JRE 和 JDK。如果只装了 JREJMeter 也能启动但编译 JSR223 脚本时会缺少编译器功能。所以安装 JDK 而不是 JRE是一个很容易被忽略的点。4.4 常用属性速查表下面是我在项目里经常用到的一组属性整理成表格方便直接参考属性名作用推荐值sampleresult.default.encoding响应结果默认解码字符集UTF-8file.encoding文件读写默认字符集通过-D传入UTF-8jmeter.csvfile.encodingCSV Data Set 文件编码UTF-8jmeter.save.saveservice.output_format结果文件保存格式csv报告用或xml调试用jmeter.save.saveservice.assertion_results是否保存断言结果truejmeter.save.saveservice.response_data是否保存响应数据true按需开启文件会变大server.rmi.port远程 Agent 主监听端口固定值如1099server.rmi.localport远程 Agent 本地回传端口固定值如1099jmeterengine.nongui.port命令行模式的控制端口0或固定端口jmeter.hidpi.mode高分屏缩放开关truejmeter.hidpi.scale高分屏缩放比例1.5log_file日志文件路径普通用户目录下的绝对路径这份表格里的属性是我在至少三个不同项目里实际验证过的。使用的时候有一个原则能用命令行的-J临时覆盖就不要改文件要长期生效的配置统一放user.propertiesjmeter.properties只在确认没有其他覆盖来源时再动。写在最后的一点个人经验属性这个东西刚接触时会觉得琐碎但把加载顺序和常用键位记牢以后你会发现 JMeter 很多“莫名其妙”的毛病都能找到明确的答案。我个人最深的体会是两句话第一遇到乱码先查编码对了八成第二遇到改了不生效先查启动参数别急着重装软件。这个工具的设计哲学其实很直白它把所有可以调的都暴露给你了关键是你得知道哪些该调、在哪里调、怎么调才不会被覆盖。最后再分享一个小技巧如果你经常要在不同项目里切换 JMeter 配置可以针对每个项目建一个独立的user.properties再通过启动命令指定属性文件的路径。JMeter 支持通过-q参数加载额外的属性文件相当于给每个项目一份独立的属性环境比每次临时改全局配置干净得多。
返回列表