ARTICLE DETAIL

资讯详情

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

JMeter 接口与性能测试实战:从脚本构建到高并发压测的完整指南

JMeter 接口与性能测试实战:从脚本构建到高并发压测的完整指南 上个月接了个活儿一套跑在单节点 Kubernetes 上的微服务应用要整体迁到云上的 ECS迁移完成后用配套的 JMeter 脚本做一轮高并发测试验证新环境的承载能力。流程上听起来不复杂但真正上手 JMeter 的人都知道这工具的功夫全在细节里——HTTPS 录制时报证书错误、BeanShell 断言写了不生效、CSV 同一个文件多线程取值互相打架、压到一半看到满屏 java.io.IOException……每一个坑都够人折腾半天。这篇文章把我这些年用 JMeter 做接口测试和性能测试的完整经验整理了一遍从安装配置讲到脚本构建、参数化、断言、100 用户并发设计、报告导出再到高频报错排查和文件上传、MQTT 插件这类进阶玩法。内容按能直接照着操作的标准写新手建议从头顺着看老手可以直接跳到对应章节捡你缺的那块。不管你是刚开始接触 JMeter还是已经写过不少脚本但总被各种报错卡住这篇都应该能帮上忙。1. 安装与基础配置版本选型、内存参数、界面缩放很多人第一步就把路走偏了随便在某某下载站找了个JMeter 安装包解压完一堆推广软件版本还是五六年前的。JMeter 是个纯 Java 工具没有传统意义的安装过程解压就能跑所以选对来源和配置比安装本身更重要。1.1 官网下载和 JDK 版本是绕不开的前提先确认你机器上的 Java 环境。JMeter 5.6 系列要求 Java 8 以上用 Java 11 或 17 都没问题如果装的是 JMeter 4.x老老实实配 Java 8。命令行先执行java -version看到版本号之后再考虑下载。下载务必去 Apache JMeter 官网jmeter.apache.org首页找到 Download 区域的 BinariesWindows 选 zip 包Linux/macOS 选 tgz 包。不要从第三方下载站拿安装包你永远不知道里面被塞了什么。Windows 上解压时注意路径别带中文和空格比如放到D:\tools\jmeter。然后进bin目录双击jmeter.batmacOS 或 Linux 打开终端执行sh bin/jmeter.sh。看到 JMeter 图形界面出来这一步就算过了。很多教材会把配置环境变量讲得特别重其实 JMeter 不配置 PATH 也能用只是以后想在任意目录直接敲jmeter命令才需要配属于锦上添花。1.2 默认堆内存不够用压测之前先调JMeter 安装包的默认 JVM 堆内存老版本只有 512MB新版本大概是 1GB。做普通接口调试没问题一旦涉及大文件上传、复杂断言、长时间并发压测分分钟报OutOfMemoryError。修改方法很简单打开bin目录下的jmeter.batWindows或jmeterLinux/macOS找到HEAP参数改成类似这样HEAP-Xms2g -Xmx2g -Xmn768m-Xms是初始堆大小-Xmx是最大堆-Xmn是年轻代大小。2GB 是建议值具体看压测机内存但别贪心堆到 8GB 以上还想着越大越稳——GC 停顿反而会让压测指标的毛刺变多。注意这个堆内存调的是 JMeter 自己这个进程跟被测服务完全无关别搞混。1.3 高分屏下界面字体太小改两个属性就解决JMeter 界面怎么调字体大小这个话题在搜索词里一直很靠前。新的 JMeter 版本在bin/jmeter.properties里默认带了两个参数不过默认是注释状态jmeter.hidpi.modetrue jmeter.hidpi.scale.factor1.5取消注释保存重启界面字体就按 1.5 倍缩放。如果还嫌小把scale.factor调到 1.75 或 2.0。旧版本没有这两个属性手动在文件末尾追加同样生效。要是你用的是 Linux 桌面改了没反应可以在启动脚本的JVM_ARGS里加-Dsun.java2d.uiScale1.5再试。1.4 插件管理器装各种扩展包只用这一个 jar搜索jmeter 插件包安装、jmeter 下载 mqtt 插件的人最后基本都会绕回同一个工具JMeter Plugins Manager。它就是一个 jar 包去 jmeter-plugins.org 下载plugins-manager.jar放进 JMeter 的lib/ext目录重启 JMeter菜单栏会多出 Options - Plugins Manager。后面要装 MQTT 插件、JSON 插件、自定义线程组全在这个管理器里勾选安装就行。这里提醒一个兼容性问题插件版本和 JMeter 主版本要对上装完必须重启 JMeter不然插件可能不生效。我在 5.4 上装新版本 MQTT 插件时遇到过加载报错最后就是换了对应版本解决的。2. 脚本构建线程组、HTTP 请求与 HTTPS 录制脚本是整个压测的地基。很多人喜欢一上来就点录制按钮结果录出来的脚本里全是一堆 CSS、JS、图片请求真正需要压的接口淹没在里面。我的习惯是先手动搭一个最简单的 HTTP 请求跑通再根据需求加复杂逻辑录制只作为辅助手段。2.1 线程组就是你的并发模型在测试计划上右键添加 - 线程用户- 线程组。线程组面板里有几个关键字段线程数、Ramp-up 时间、循环次数、调度器。这几个值的含义必须吃透因为它们直接决定你模拟的是什么场景。线程数同时发起请求的虚拟用户数。Ramp-up 时间多少秒内把这么多线程全部启动。循环次数每个线程执行多少遍。调度器勾选后可以设置持续时间比如压 10 分钟。举例模拟 100 个用户并发可以直接填线程数 100Ramp-up 填 40意思是每秒启动 2~3 个用户40 秒后达到 100 并发。Ramp-up 不是随便填的数字它模拟的是真实用户逐步进入系统的过程直接把 Ramp-up 设成 0 会让 100 个线程在同一瞬间打过去先冲击一波连接层容易把结果带偏。循环次数如果填 100总请求量就是 100 线程 × 100 循环如果用调度器设持续时间 10 分钟就不需要关心循环次数跑完时间自动停。压测时我更推荐持续时间 调度器的模式因为真实场景一般不关心跑了多少次循环只关心单位时间内的请求量和系统表现。2.2 HTTP 请求面板里 RESTful 参数到底怎么填这是搜索量很高的话题jmeter restful 参数怎么写。先分清你请求的是什么类型GET 请求带查询参数。比如GET /api/orders?status1page2在 HTTP 请求采样器里方法选 GET路径填/api/orders下面 Parameters 表格里加两行status1page2。不必自己在路径里拼问号JMeter 会自动拼。路径参数。RESTful 风格里最常见的/api/orders/123这种直接把路径写成/api/orders/${orderId}${orderId}可以来自 CSV、变量、正则提取器。很多新手在这里犯迷糊以为路径参数也得填到 Parameters 表格里结果请求发出去变成/api/orders/123?orderId123接口自然 404。POST 提交 JSON。先在测试计划里加一个 HTTP 信息头管理器加一行Content-Type: application/json然后在 HTTP 请求面板切到 Body Data直接写 JSON{ name: ${name}, age: ${__Random(20,60)} }Body Data 里的 JSON 字符串支持变量引用所以参数化数据源照样能套进来。有一点容易踩如果接口对 Content-Type 要求苛刻比如必须是application/json;charsetUTF-8别偷懒把完整值写进头管理器不然服务端可能返回 415。PUT/DELETE 同理无非是方法换一下Body 或参数按上面规则填。2.3 监听器先别堆太多会拖垮压测机新手最常见的操作是脚本没跑先往测试计划里拖五六个查看结果树、聚合报告、断言结果。调试阶段没问题但真压测时这些监听器都是内存怪兽尤其是查看结果树它会为每条响应保存完整内容压到几千上万个请求时JMeter 自己的内存先爆了压测机变成瓶颈数据全废。我的建议调试用查看结果树每确认一个请求没问题就把它删掉或禁用。正式压测只在脚本里保留一个简单数据写入器Simple Data Writer把结果落盘然后跑完后用命令行生成报告。这个习惯能帮你省掉大量为什么压测机 CPU 100% 但被测服务很闲的疑惑。2.4 HTTPS 脚本录制和根证书的处理流程jmeter 录制 https 脚本和jmeter 安全证书其实是一件事JMeter 录制 HTTPS 流量时要在浏览器和 JMeter 之间做一个中间人代理浏览器必须信任 JMeter 临时生成的那个根证书否则握手直接失败。完整步骤我理成一条线测试计划下右键添加 - 非测试元件 - HTTP(S) 测试脚本记录器。记录器面板设置端口默认 8888Target 控制器选到你的线程组。启动记录器前JMeter 会在bin目录生成一个ApacheJMeterTemporaryRootCA.crt证书文件也可以点菜单 Options - SSL Manager 查看。浏览器设置代理指向127.0.0.1:8888。安装证书Windows 上双击 crt 文件导入到受信任的根证书颁发机构Chrome/Firefox 各自有证书管理入口手机抓包就把证书装到手机上iOS 还要额外去设置 - 通用 - 关于本机 - 证书信任设置里打开开关。证书装好、代理配上之后在浏览器里操作被测系统JMeter 就会把请求录进指定线程组。踩坑提示很多 HTTPS 报错都是证书安装不完整导致的。比如 Chrome 会显示您的连接不是私密连接但代理又能通这时候优先检查证书是否真的进了受信任的根证书颁发机构而不是看一遍又一遍地重新录制。另外有个态度问题录制出来的脚本默认包含大量静态资源请求压测前必须过滤掉图片、CSS、JS只保留核心接口否则你压的不是业务是在压带宽和静态文件服务器。3. 参数化数据驱动测试的三种主流玩法接口测试和压测最核心的能力之一就是参数化。一组相同的请求压不出真实场景真实用户每个人发的数据都不一样。JMeter 里参数化有三条主流路线CSV 文件、数据库查询、内置函数。3.1 CSV 数据文件同一个文件里线程分块取值怎么搞搜索词里有一条特别具体jmeter 在同一个 csv 参数化文件中每个线程分块取值。这确实是容易搞混的点。先加一个 CSV 数据文件设置配置元件 - CSV 数据文件设置字段含义文件名CSV 路径支持相对路径。变量名称逗号分隔对应 CSV 每一列。分隔符默认逗号。文件编码强烈建议填utf-8。共享模式下拉框里有 All threads、Current thread group、Current thread。共享模式是理解分块取值的关键。很多人以为选 Current thread 就是每个线程各拿一块数据这个理解是错的。Current thread 表示每个线程各自打开这个文件、各自从头开始读结果就是所有线程读到的数据一模一样根本不是分块。真正让数据不重复的是 All threads 模式全局共享一个游标每次取一行取完自动往下走不同线程拿到的行天然不重叠。那如果我就是想让线程 1 拿第 1~10 行线程 2 拿第 11~20 行这种物理分块呢最省事的做法不是在一个文件里做文章而是按线程号拆文件。JMeter 内置了__threadNum函数能拿到当前线程号所以 CSV 文件名可以动态写成data_${__threadNum}.csv配合共享模式选 Current thread每个线程就从自己的文件块里取数互不干扰。这个方案我实测过多线程下稳定可靠缺点是要预先拆好文件适合数据量可控的场景。还有一个高频坑CSV 文件用 UTF-8 带 BOM 格式保存时JMeter 读出来的第一列变量名会带着\ufeff前缀接口莫名其妙就多了个特殊字符。解决方式是用 Notepad 或 VS Code 另存为 UTF-8 无 BOM。3.2 JDBC Request把数据库查询结果喂给下一个接口jmeter 数据库参数化取值、jmeter jdbc request 参数化、jmeter 将 jdbc request 查询出的数据作为下一个接口的参数这三条搜索词说的是同一个需求从数据库查一批真实数据作为接口参数去发请求。完整链路分三步。第一步准备数据库驱动。以 MySQL 为例下载mysql-connector-java的 jar 包扔进 JMeter 的lib目录。注意版本MySQL 5.x 对应驱动类名是com.mysql.jdbc.DriverMySQL 8.x 要换成com.mysql.cj.jdbc.DriverURL 一般写成jdbc:mysql://127.0.0.1:3306/yourdb?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai第二步添加 JDBC 连接配置。右键测试计划 - 配置元件 - JDBC Connection Configuration。关键点Variable Name for created pool随便起个名字比如dbPool但必须跟后面的 JDBC Request 里填的变量名完全一致这是两者关联的钥匙。第三步添加 JDBC Request 采样器。SQL 写查询语句select id from user where status 1 limit 5然后在变量名Variable Name填dbPool下面的 Result variable name 填一个结果变量名比如users。执行之后JMeter 会生成这些引用变量${users_#}总行数${users_1}第一行第一列的值${users_2}第二行第一列的值多列场景用${users_1_userid}这种形式取指定字段拿到这些值之后在下一个 HTTP 请求的参数或 Body Data 里直接写${users_1}就完成了数据库查出来的数据作为下一个接口参数这个动作。如果要把多行数据循环发给不同请求可以配一个循环控制器或ForEach 控制器配合${users_${i}}动态取值。这个玩意的实用性极高特别是在做业务链路压测时用生产库里的真实 ID 列表去压远比随机数更能发现参数校验层面的问题。但注意别把数据库放在和压测机同一台机器上JDBC 查询本身也有开销别让它污染压测结果。3.3 常用函数Random、counter、threadNum 怎么配合除了 CSV 和数据库JMeter 函数是最轻量的参数化手段。用得最多的是这几个${__Random(1,100)}随机生成 1 到 100 的整数适合模拟手机号后四位、随机金额。${__counter(TRUE,)}全局计数器TRUE 表示每个线程独立计数FALSE 是全局共享。${__threadNum}当前线程号从 1 开始。${__time(yyyy-MM-dd HH:mm:ss,)}格式化当前时间适合生成时间戳参数。一个常见需求是生成随机手机号可以这样组合138${__Random(10000000,99999999)}函数可以用在 HTTP 请求的路径、参数、Body Data、断言里任何地方。但注意函数嵌套层数不要太多否则脚本可读性急剧下降维护起来想骂人。4. 断言与校验从响应码到 BeanShell 的进阶接口测试里有个悲剧场景响应状态码全是 200脚本绿得发亮但业务上其实全错了——比如订单创建接口因为库存不足返回了 200 加一个错误提示或者登录接口返回了 200 但里面是个验证码错误页面。所以断言必须做而且不能只看状态码。4.1 响应断言匹配规则选错等于白做添加 - 断言 - 响应断言。核心配置是两个下拉框要测试的响应字段一般选响应文本或者响应代码。匹配规则Contains、Matches、Equals、Substring 几个选项。这里的坑非常典型Contains 和 Matches 用的是正则表达式匹配Equals 和 Substring 是字符串字面量。很多人想判断响应文本是不是包含 success。如果用 Contains填的success会被当成正则success这种看起来差不多但带正则语法的东西很容易误判如果只想做字面匹配应该选 Substring性能也更好。举个例子断言响应文本包含成功我会这样配要测试的响应字段响应文本匹配规则Substring测试模式成功再加上一个断言响应代码等于 200让两层校验同时生效。4.2 用 JSON 提取器把上一个接口的返回值传给下一个接口链路的测试里最常用的是 JSON 提取器登录接口返回 token下一个接口的请求头要带这个 token。这是我见到最多的真实场景。在登录请求上右键添加 - 后置处理器 - JSON 提取器变量名称tokenJSON 路径表达式$.data.token默认值NOT_FOUND跑完登录请求${token}就有值了。然后在下一个接口的 HTTP 信息头管理器里加一行Authorization: Bearer ${token}链路就串起来了。如果接口返回的不是严格 JSONJSR223 后置处理器里用 Groovy 处理字符串或 JSONObject 更灵活但 JSON 提取器覆盖了绝大多数需求写法也最直观。4.3 BeanShell 断言怎么写以及什么时候别用jmeter beanshell 断言也是长年热搜。BeanShell 断言的优势是自由度高能在断言里写 Java 语法逻辑。最基础的写法是这样String response prev.getResponseDataAsString(); if (response.contains(success)) { Failure false; } else { Failure true; FailureMessage 响应中未找到 success 关键字; }prev是 SampleResult 对象vars是变量操作对象log是日志对象Failure 和 FailureMessage 是断言结果标识这几个是 BeanShell 断言里的常用内置对象。想更狠一点可以直接解析 JSON 判断业务字段import org.json.JSONObject; String resp prev.getResponseDataAsString(); JSONObject obj new JSONObject(resp); String code obj.optString(code); if (!200.equals(code)) { Failure true; FailureMessage 业务 code 非 200实际是: code; }注意org.json 这个包在 JMeter 的lib目录里自带所以可以直接 import。这东西在调试阶段非常好用但你必须知道它的性能缺陷BeanShell 是解释执行的每来一个请求就要解释一遍脚本高并发压测时它会成为 JMeter 自身的瓶颈。压测脚本里我强烈建议用 JSR223 采样器 Groovy 语言替代 BeanShell语法基本兼容执行方式却是编译级别性能完全不是一个档次。5. 压测执行与报告解读100 用户并发怎么设计jmeter 模拟 100 用户并发报告这种搜索词说明很多人到了压测阶段被到底填多少线程、Ramp-up 怎么设、报告怎么看卡住了。这部分我直接给一套可复用的方法。5.1 并发模型设计线程数、Ramp-Up、循环次数怎么配假设目标就是 100 用户并发我建议这样设计线程数100Ramp-up60 秒循环次数勾选永远同时勾选调度器持续时间设 600 秒10 分钟Ramp-up 设 60 秒的考虑100 个线程在 60 秒内均匀启动大约每秒新增 1~2 个用户这个斜率相对温和能避免启动瞬间的流量尖峰。如果目标接口平时就很吃资源可以把 Ramp-up 拉长到 120~180 秒。但更严谨的做法是分阶段压测不要一上来就 100 并发。我第一次压新环境时永远先在 CLI 模式下用 10 并发跑 2 分钟冒烟确认无错误、响应均值正常再逐步加并发到 100。理由很简单如果脚本本身有参数错误小并发能让你快速发现并修正大并发只会让你面对一堆放大后的噪音。还有个容易被忽略的点压测机的资源要富余。100 并发听起来不大但如果每个响应体都比较大JMeter 所在机器的 CPU 和内存会先吃紧。压测机部署在被测服务之外的机器上这是基本素养。5.2 察看结果树导出和 CLI 模式下的报告生成排查问题时察看结果树最直观但它的导出功能很多人在搜索。察看结果树面板上方有一个小软盘图标选中某条结果后点击可以保存该条请求和响应的详细信息保存的是 XML 格式文件路径自己选。但说实话单条导出的用处有限真正的压测留痕要做全量结果落盘。最标准的做法是用命令行跑压测并把结果文件和报告分开jmeter -n -t script.jmx -l result.jtl -e -o report_html参数含义-n非 GUI 模式-t指定脚本-l指定结果文件JTL 或 CSV-e生成 HTML 报告-o报告输出目录。执行完会在report_html目录下生成一整套页面里面有 APDEX 指数、响应时间分布图、吞吐量、错误率还带各种百分位线比截图聚合报告专业得多。这里有一个高频报错如果result.jtl或报告目录已经存在JMeter 会直接报 File already exists 之类的错误。解决办法是在命令后面加一个强制删除参数jmeter -n -t script.jmx -l result.jtl -e -o report_html -f-f表示强制清掉旧文件。或者每次跑之前手动删干净。5.3 聚合报告里先看哪几个指标聚合报告是压测人群里最常见的截图对象里面的字段我建议按这个优先级看指标含义关注点Samples请求总数样本是否足够太少没有统计意义Average平均响应时间整体体感但会被极端值拉偏Median中位数50% 请求的响应时间比均值更稳定90% / 95% / 99% Line百分位响应时间长尾场景最该看95%、99% 决定用户体验上限Min / Max最慢最快Max 往往能定位到某次超时或 GC 停顿Error %错误率压测能否继续的关键一般要求低于 1%Throughput吞吐量req/s系统承载能力的核心指标举个例子某个接口跑 100 并发 10 分钟聚合报告显示 Average 350ms、Median 200ms、95% Line 800ms、99% Line 1.2s、Error 0.1%、Throughput 180 req/s。这个结果说明大部分请求响应很快但存在少量长尾请求1.2 秒的 99% 线如果超过业务方给的 SLO比如 P99 ≤ 1s那就还得继续调优。只会看平均值很容易被平均骗过去均值低但 P99 爆炸的系统多得很。6. 高频报错与经典坑位排查从报错信息倒推根因搜索引擎里 JMeter 相关的报错提问非常多我把几个真正高频的拎出来每个都写清楚排查链路而不是直接给结论因为同一个报错在不同环境下根因完全不同。6.1 java.io.IOException: error writing to server这个报错在长时间压测中非常常见。字面意思是往服务器写数据的时候 IO 出错通俗讲就是 JMeter 正准备把请求体发给服务端连接已经断了。排查链路我一般这样走先确认是不是偶发把报错条数和总请求量对比。如果只有零星几条大概率是服务端主动断开了空闲连接比如 Nginx 的keepalive_timeout设得太短或者 Tomcat 的connectionTimeout触发。看服务端日志报这个错的同时服务端一般会有Connection reset by peer或Broken pipe的对应记录。如果是说明服务端因为某种原因关闭了连接——可能是线程池满了、数据库连接池耗尽、或者请求处理时间超出了网关超时。排查请求体大小上传场景里请求体过大而服务端或网关限制了client_max_body_size也会触发类似报错。此时报错通常集中在大文件请求上特征很明显。检查 JMeter 的 HTTP 客户端实现在 HTTP 请求的高级选项卡里Implementation 可以选 HttpClient4 或 Java。不同实现处理连接复用的方式不一样如果服务端对连接管理很敏感换一个实现有时能绕开。这个报错没有银弹关键是把 JMeter 报错和服务端日志对上谁先断谁就是根因。6.2 MVC 项目提示 __RequestVerificationToken 未提供必要的防伪标记这条搜索词一看就是测试 ASP.NET MVC 项目的人问的。MVC 的防伪机制要求 POST 请求里带一个__RequestVerificationToken隐藏字段并且这个字段的值通常还要和同名 Cookie 绑定。如果你直接用 JMeter 发 POST没有这个 token服务端直接拒绝。解决链路先用 GET 请求打开那个页面或者找到登录接口所在页面拿到 HTML 里的 token。一般是个隐藏字段input name__RequestVerificationToken typehidden valuexxxx /用正则表达式提取器把它提取出来name__RequestVerificationToken typehidden value([^])在 POST 请求的参数表里加一行参数名就叫__RequestVerificationToken值引用${token}。别忘了加 HTTP Cookie 管理器因为 MVC 防伪机制校验 token 和 cookie 的绑定关系cookie 丢了照样报错。如果那个站点是通过 AJAX 提交并把这个 token 放在请求头里就把参数方式换成请求头RequestVerificationToken: ${token}。判断标准是看页面里的 form 提交方式这个坑我写过挺多次了每次都能帮人省两小时。6.3 文件已存在、MySQL 密码、中文乱码之类的日常坑文件已存在前面提过CLI 模式加-f强制覆盖或者换新的输出文件名。MySQL 密码带特殊字符JDBC URL 里有、%之类的字符需要 URL 编码不然连接串会被截断解析错误。响应中文乱码在jmeter.properties里把sampleresult.default.encoding从ISO-8859-1改成UTF-8或者每个请求单独在头管理器里加Content-Type: application/json;charsetUTF-8。CSV 参数化取出来的中文乱码优先检查文件编码是不是 UTF-8 无 BOM这个前面也说过。7. 业务场景实战上传文件、MQTT 插件与云迁后的压测验证最后这块写几个真实业务场景也是搜索词里集中出现的jmeter 上传文件、jmeter 下载 mqtt 插件和云环境迁移验证的完整动作。7.1 文件上传用例怎么做才不容易翻车HTTP 请求采样器里方法选 POST勾选Use multipart/form-data然后在文件上传页签里配置文件路径本机真实存在的文件路径比如D:\testdata\order.xlsx参数名称接口要求的字段名比如fileMIME 类型application/vnd.openxmlformats-officedocument.spreadsheetml.sheet或者application/octet-stream同一个上传接口一般还要带几个业务参数比如订单号、用户 ID这些填在参数表格里JMeter 会一起拼进 multipart 请求体。容易踩的坑有两个一是压测机上文件路径必须存在别在 GUI 机器上配好了路径生成 JMX 后扔到 Linux 压测机上跑路径不存在全部失败二是服务端不允许同名文件重复上传时第二次压测请求会返回文件已存在。解决方式是在文件名里拼上时间戳或随机数比如D:\testdata\order_${__time(yyyyMMddHHmmss)}.xlsx但这样会不停生成新文件记得在测试方案里约定清理策略。补充一点大文件上传时 JMeter 自身内存消耗会明显上升建议压测前把堆内存调大并且观察压测机的 IO 和内存避免把脚本机压垮。7.2 MQTT 插件物联网场景下的消息压测jmeter 下载 mqtt 插件说的其实是 MQTT Protocol Support这个是纯插件不是 JMeter 自带的。按 1.4 节装好插件管理器后在 Plugins Manager 里搜 MQTT勾选安装重启 JMeter就能在采样器列表里看到 MQTT Connect、MQTT Pub Sampler 和 MQTT Sub Sampler。典型玩法分三段MQTT Connect配置 broker 地址比如tcp://192.168.1.10:1883设置 clientID。注意并发场景下 clientID 不能重复JMeter 这里可以用${__threadNum}生成带线程号的 clientID。MQTT Pub Sampler发布消息topic 比如device/${deviceId}/telemetrypayload 填 JSON 数据QoS 按业务要求选 0/1/2。MQTT Sub Sampler订阅主题用来验证消息有没有正确到达或者作为命令下发的消费端。MQTT 压测的核心指标是消息吞吐和端到端时延。注意如果 broker 启用了 TLS 鉴权连接地址要换成ssl://并配合证书管理器处理双向认证这个复杂度比 HTTP 高不少建议先在测试环境把连接串弄通再上压测。7.3 单节点环境迁云之后用配套脚本验证承载能力的完整流程开头提到的场景——单节点 Kubernetes 上跑微服务迁移到云上 ECS 之后由压测人员拿配套的 JMeter 脚本做高并发测试验证承载能力——我把完整流程写出来这也是很多运维和测试同行会遇到的真实任务。第一步确定指标口径。和业务方对齐承载能力具体是什么目标 QPS 多少、P95 响应时间多少、错误率上限多少、压测持续时间多长。没有这些数字后面跑出来的报告就是一堆没有结论的数据。第二步脚本自检。拿到别人给的 JMeter 脚本先在 5~10 并发下冒烟跑一遍确认接口路径、参数、断言在这个新环境里全部正常。迁移后的服务可能换了域名、换了数据库连接、改了端口脚本里硬编码的地址必须逐项核对。第三步阶梯加压。不要一上来就 500 并发。我常用的阶梯是50 并发跑 10 分钟100 并发跑 15 分钟200 并发跑 15 分钟后面按目标值继续加。每一档都要保留对应的 JTL 结果文件比如result_50.jtl、result_100.jtl方便事后做横向对比。第四步CLI 模式执行。把脚本和 CSV 数据文件放到压测机用 5.2 节的命令行跑。压测期间同时打开云监控面板看 ECS 的 CPU、内存、磁盘 IO、带宽以及微服务各实例的连接数和 GC 情况。压测数据和系统监控数据要放在同一时间轴上对比才有意义。第五步结论输出。把每一档的聚合报告、HTML 报告、系统监控截图汇总明确回答三个问题新环境能不能扛住目标并发在哪个并发量出现拐点响应时间陡增或错误率抬头瓶颈在服务本身还是数据库、缓存、网关。这一步做完迁移验证才算真正闭环。这个流程里我最想提醒的一点是迁移类压测的目的不是把系统压崩而是找出新环境上线后业务还能不能按原承诺运行。所以每一档压测之间要留出恢复时间随时准备叫停别让压测把新环境搞出生产事故。最后再分享一个小习惯每次正式压测的前一天我会把脚本用非 GUI 模式空跑一遍确认依赖的 CSV 路径、输出目录、报告目录全部就绪。这个不起眼的动作已经救过我很多次——至少三次是因为前一天改了 CSV 文件名没同步到脚本第二天压测一启动就是满屏文件找不到。JMeter 本身并不难难的是把所有细节都安排得明明白白。希望这份教程能让你少踩几个我踩过的坑脚本一次就跑顺。
返回列表