
项目脚本在 GUI 里跑得好好的断言全绿结果一到服务器侧看日志发现请求体里少了字段、参数被多编码了一层、某个自定义 Header 压根没发出去。这种时候光盯着 JMeter 的 View Results Tree 是没用的它只告诉你返回了什么不告诉你实际发出了什么。想看清这条链路最直接的办法是把 Fiddler 塞到 JMeter 和被测服务中间让每一个字节都从它眼皮底下过一遍。这篇就把用 Fiddler 抓 JMeter 请求这件事从头拆到尾为什么 JMeter 默认绕过 Fiddler、三条把流量导进去的路子怎么挑、HTTPS 那道证书坎怎么迈、抓不到包时按什么顺序排查、抓到之后怎么把会话变成结论。适合刚接手接口脚本、被编码和证书问题折磨过的测试同学也适合想搞明白代理机制的开发。1. 先把原理捋顺JMeter 的请求为什么天生绕开 Fiddler1.1 JMeter 读的是 JVM 系统属性不是操作系统的代理设置很多人第一次做这件事的顺序是这样的在系统设置里打开代理指向 127.0.0.1:8888然后浏览器访问网页Fiddler 里哗哗出会话心里一阵踏实。接着启动 JMeter 跑一遍脚本回头一看 Fiddler干干净净一条记录都没有。于是开始怀疑 Fiddler 坏了、端口被占、防火墙拦了折腾半小时。真相很简单操作系统那一层的代理设置只对遵循系统代理约定的程序生效典型代表是浏览器这一类走系统网络栈的应用。JMeter 是跑在 JVM 上的 Java 程序它的 HTTP 采样器底层用的是 Apache HttpClient取代理信息的方式是读 JVM 的系统属性http.proxyHost、http.proxyPort、https.proxyHost、https.proxyPort外加一份http.nonProxyHosts白名单。你在系统设置里改的东西JVM 一个字节都读不到。Linux 和 macOS 下习惯性export HTTP_PROXY...的做法同样不管用因为 JMeter 的 HttpClient 并不去读环境变量。这就解释了一个常见现象同样的代理设置浏览器能抓、curl 能抓、Postman 能抓唯独 JMeter 抓不到。不是 JMeter 特殊是它老老实实按 Java 的规矩走而 Java 的规矩和你想象中的规矩不是一套。记住这条给 JMeter 配代理配的是 JVM 系统属性不是操作系统代理。这个认知错位是九成抓不到包问题的根。1.2 Fiddler 在链路里扮演的角色以及 HTTPS 时它做了什么手脚Fiddler 本质上是个本地 HTTP 代理服务器默认监听 8888 端口。当 JMeter 被配置成走127.0.0.1:8888之后一条 HTTP 请求的走向会变成JMeter 把请求行写成绝对地址形式GET http://demo.internal.test/api/v1/items HTTP/1.1发到 FiddlerFiddler 解析出真实主机自己再和服务端建一条新连接转发过去服务端响应回来Fiddler 再转回给 JMeter。这里有个细节值得说清楚JMeter 和 Fiddler 之间是一条 TCP 连接Fiddler 和服务端之间是另一条。所以你在 Fiddler 里看到的连接耗时、TCP 握手信息跟 JMeter 实际经历的网络路径并不完全一致做性能分析时别看串了。HTTPS 的流程要复杂一层。JMeter 首先向 Fiddler 发一条CONNECT demo.internal.test:443 HTTP/1.1Fiddler 回HTTP/1.1 200 Connection Established握手通道打通。紧接着 TLS 握手开始此时 Fiddler 并不真的去和 JMeter 讲我是代理而是现场用自己签发的证书冒充demo.internal.test把 TLS 会话先接住然后它再去和真服务端完成另一次 TLS 握手两头解密再加密中间明文它自己留着看。这套机制能跑通的前提只有一个JMeter 这一侧的 JVM 信任 Fiddler 那张根证书。否则 TLS 握手在证书校验环节就断了你只能在 Fiddler 里看到一条孤零零的 CONNECT看不到任何明文——这就是后面第 3 章要重点解决的事。1.3 动手之前必须先问自己的三个问题在敲任何命令之前先把这三件事想明白能省掉一大半返工。第一JMeter 和 Fiddler 是不是在同一台机器上。同机的话代理地址填127.0.0.1就行最省事。如果是 JMeter 跑在 Linux 压测机上、Fiddler 装在本地 Windows那 Fiddler 必须打开允许远程连接并且在防火墙放行 8888JMeter 侧填的是 Fiddler 所在机器的局域网 IP。跨机场景还要注意一点流量会真的绕一圈延迟和带宽都不代表真实情况。第二被测地址是不是本机或内网回环。Java 默认的http.nonProxyHosts里包含localhost|127.*|[::1]这类条目意思是访问这些地址不走代理。如果你的脚本打的是本机起的服务代理配了也白配请求会规规矩矩地直连。这种情况需要把http.nonProxyHosts显式清空或改写。第三目标是不是 HTTPS以及服务端证书是不是自签的。如果是自签证书问题会变成双重的JMeter 既要信任 Fiddler 的根证书Fiddler 又要能接受服务端的自签证书。两层都得处理缺一不可。很多人只处理了第一层然后困惑为什么 Fiddler 里能看到请求但服务端返回 502。2. 把 JMeter 流量导进 Fiddler 的三条路按场景挑2.1 命令行 -H 与 -P临时调试最省事的一条路JMeter 的命令行工具本身就带代理参数这四个值得记住-H代理主机-P代理端口-N非代理主机列表对应http.nonProxyHosts-u/-a代理的用户名和密码代理需要认证时用一个最典型的不带界面的调用长这样# Windows 下在 JMETER_HOME/bin 目录执行 jmeter -n -t order_flow.jmx -l result.jtl \ -H 127.0.0.1 -P 8888 \ -N Linux 下同理注意-N 在某些 shell 里会被吞掉稳妥的写法是直接把非代理列表显式写成你不需要绕过的样子jmeter -n -t order_flow.jmx -l result.jtl \ -H 127.0.0.1 -P 8888 \ -N no-such-host.invalid用-H/-P的好处是改动零侵入脚本文件一个字都不用动别人拿去做正式压测时也不会因为残留的代理配置把流量导到不存在的端口上。坏处是每条命令都得带着容易忘而且它只影响 HTTP/HTTPS 采样器对 JDBC、JUnit、TCP 采样器无效——这点在混合场景里要留意别指望它把所有流量都截下来。还有一个容易忽略的优先级问题如果某个 HTTP 请求采样器自己已经填了 Proxy Server 字段那采样器级别的配置会覆盖命令行给的全局值。排查为什么这条请求不走代理时先去采样器的 Advanced 面板看一眼别一上来就怀疑命令行。2.2 写进 system.properties一次配置所有启动方式都生效如果你有一台专门用来调试脚本的机器或者整个团队都用同一套环境那把代理写进配置文件更合适。这里有个关键区分必须讲清楚很多教程含糊带过结果照抄了却不生效jmeter.properties里放的是 JMeter 自己的属性system.properties里放的才是 JVM 系统属性。代理属于后者。你在jmeter.properties里写http.proxyHost127.0.0.1基本是白写因为 JMeter 不会把它当成 JVM 属性用。正确的落点是JMETER_HOME/bin/system.properties追加这么几行# bin/system.properties http.proxyHost127.0.0.1 http.proxyPort8888 https.proxyHost127.0.0.1 https.proxyPort8888 # 清空非代理列表避免打本机服务时被绕过 http.nonProxyHosts https.nonProxyHosts改完重启 JMeter 才会生效因为系统属性是在 JVM 启动时读入的GUI 里面改不了。这也是它相对命令行的一个劣势切换抓包/不抓包两种状态要改文件、要重启不够灵活。好处是团队里谁拿到这台机器都能直接复现不用记一长串参数。提示system.properties是共享文件提交到代码库里之前先把代理配置注释掉或者删掉。我见过不止一次某人调完脚本忘了删第二天同事在另一台机器上跑同一套脚本所有请求全部指向 127.0.0.1:8888全线报连接拒绝查了半天以为是服务挂了。2.3 采样器级别填 Proxy Server只抓你想抓的那一条第三种方式颗粒度最细在 HTTP 请求采样器的 Advanced 面板底部有 Proxy Server 一栏填主机和端口即可。它最大的价值是精准——一个计划里如果有二十个接口你只想查其中三个的请求体就不必让全部流量都绕道代理避免其他接口因代理引入的额外延迟和偶发失败干扰判断。这里分享一个真正省事的技巧不要对着每个采样器挨个填用HTTP Request Defaults统一配一次就行。同一线程组里所有没单独覆盖该字段的 HTTP 采样器都会继承这个默认值。需要临时排除某一条时再在那条采样器上单独清空该字段或填一个非代理的空值。这套做法比全局配置灵活得多尤其是在一个测试计划里同时包含要抓包的接口和纯压测的接口时。三种方式放在一起对比大致是这样方式生效范围改动成本适合场景主要坑点命令行-H/-P全局仅 HTTP/HTTPS 采样器低不改文件临时调试、无界面运行每次都要带参数易忘system.properties全局所有启动方式中需重启固定调试机、团队共用环境误提交对 JMeter 属性/系统属性混淆采样器 Proxy Server精确到单条请求高但可用 Defaults 摊薄混合场景只抓部分接口逐条填写易漏优先级高于全局选择逻辑其实很简单一次性排查走命令行长期固定环境走配置文件只想看几条请求走采样器加 Defaults。3. HTTPS 才是真正的坎让 JMeter 的 JVM 信任 Fiddler 的根证书3.1PKIX path building failed到底在抱怨什么代理配好第一次跑 HTTPS 脚本十有八九会在 JMeter 的日志里撞见这几行javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target直译一下就是JVM 拿着服务端递过来的证书想沿着签发链一路往上追到某个自己信任的根追到一半断了找不到可信的锚点。因为此刻递给它证书的服务端其实是 Fiddler 假扮的签发者是 Fiddler 自己生成的根证书而 JVM 的信任库cacerts里压根没有这张证书。注意这个报错跟证书过期域名不匹配完全是两回事别顺着那几个方向查。判断方法很直接把代理关掉、让 JMeter 直连同一个地址如果请求恢复正常那就百分百是信任链的问题而不是服务端证书本身有问题。顺带说一个高频误区很多人以为在 Fiddler 里点了Decrypt HTTPS traffic、点了Trust Root Certificate问题就解决了。这两个动作只把 Fiddler 的根证书装进了Windows 的证书存储区让浏览器和走系统证书库的程序信任它。JVM 用的是自己的cacerts文件跟 Windows 证书库是两套东西井水不犯河水。所以浏览器抓 HTTPS 一片绿JMeter 抓 HTTPS 一片红是完全正常的。3.2 导出 Fiddler 根证书并用 keytool 建一个独立信任库第一步把 Fiddler 的根证书导出来。在 Fiddler 里依次进入 Tools → Options → HTTPS点 Actions选择 Export Root Certificate to Desktop桌面上会多出一个FiddlerRoot.cer。第二步用 JDK 自带的keytool把它导进一个新建的信任库。这里强烈建议新建而不是直接往 JDK 的cacerts里塞理由后面说。# 先确认 keytool 可用路径要和 JMeter 用的 JDK 一致 keytool -version # 新建信任库并导入 Fiddler 根证书 keytool -importcert -noprompt \ -alias fiddlerroot \ -file FiddlerRoot.cer \ -keystore fiddler-truststore.p12 \ -storetype PKCS12 \ -storepass changeit几个参数值得解释一下。-alias是这条证书在库里的别名起个能认出来的名字将来要删的时候方便。-noprompt表示不交互确认脚本化时必备。-storetype PKCS12是因为新版本 JDK 早就不用 JKS 作为默认格式了显式写清楚能避免老教程和新环境对不上号。-storepass设的密码在下面挂参数时要用到别设成自己都记不住的东西。为什么不建议直接往cacerts里塞因为那是整个 JDK 的全局信任库你往里面加了一张 Fiddler 的根证书等于这台机器上所有 Java 程序都无条件信任它签发的任何证书。调试期无所谓但如果这台机器还跑着别的服务或者团队里有多人共用这个改动的影响面就太大了而且事后很容易忘掉自己改过。单独建一个 truststore、只在需要抓包的那次启动里挂上去是干净得多的做法。注意keytool必须用 JMeter 实际使用的那套 JDK 里的。机器上装了多个 JDK 是常事用 A 的 keytool 生成信任库、JMeter 却跑在 B 上虽然 PKCS12 格式通用一般不会出问题但版本差异带来的算法兼容问题偶尔会咬人。用jmeter -v能看到它用的 Java 版本和路径。3.3 把信任库挂到 JMeter 启动参数上的两种写法有了信任库接下来要把路径告诉 JVM。两个系统属性javax.net.ssl.trustStore信任库文件路径javax.net.ssl.trustStorePassword信任库密码写法一命令行临时挂jmeter -n -t order_flow.jmx -l result.jtl \ -H 127.0.0.1 -P 8888 \ -Djavax.net.ssl.trustStore/path/to/fiddler-truststore.p12 \ -Djavax.net.ssl.trustStorePasswordchangeit注意这里是-D不是-J。JMeter 的命令行里-D设的是 Java 系统属性直接进 JVM-J设的是 JMeter 自己的属性。搞混了就是参数写了但没生效的经典来源。Windows 下路径建议用正斜杠D:/tools/fiddler-truststore.p12反斜杠容易被当成转义符。写法二写进bin/system.propertiesjavax.net.ssl.trustStoreD:/tools/fiddler-truststore.p12 javax.net.ssl.trustStorePasswordchangeit同样需要重启生效。这条写法和第 2.2 节的代理配置放在一起就构成了一套完整的抓包模式配置用的时候打开、不用的时候注释掉比每次记命令行靠谱。配好之后重新跑如果 Fiddler 里能看到完整的 HTTPS 请求和响应明文Inspectors里能查看到请求体那就通了。如果还是握手失败先确认信任库路径没写错-D参数里路径有空格会截断尽量放在无空格的目录再确认keytool列出来的内容里确实有那条别名keytool -list -keystore fiddler-truststore.p12 -storepass changeit3.4 服务端用自签证书时的第二层信任上一节解决的是JMeter 信任 Fiddler。如果被测服务端自己用的也是自签或内部 CA 签发的证书那 Fiddler 这一侧还得能接受它否则 Fiddler 转发时照样报错通常表现为 Fiddler 会话变红、状态码 502。处理办法是把服务端那张证书也导进同一个信任库用不同的别名keytool -importcert -noprompt \ -alias targetserver \ -file server-cert.cer \ -keystore fiddler-truststore.p12 \ -storetype PKCS12 \ -storepass changeit因为 Fiddler 和 JMeter 共用同一套 JVM 信任配置Fiddler 本身跑在 .NET 上但它的证书校验走系统证书库所以严格说是两边都要处理。更省事的替代方案是在 Fiddler 的 HTTPS 选项里勾选忽略服务端证书错误只在你明确知道目标环境是内网测试环境时用别把这个开关带到任何对外的场景里。还有一条更轻量的路子如果这次调试只关心请求体长什么样完全不需要解密那就在 Fiddler 的 HTTPS 设置里关掉Decrypt HTTPS traffic让它只做隧道透传。好处是不用碰证书坏处是看不到任何明文只能看到 CONNECT 和字节数。什么时候够用当你的问题是请求到底发没发出去有没有重试连接耗时多少时透传就够了。4. 抓不到、抓一半、抓到假的典型故障的排查链路4.1 会话列表一片空白一条记录都没有按顺序往下排不要跳步。第一层Fiddler 到底有没有在监听。看 Fiddler 左下角状态栏正常会显示Capturing和监听端口。如果显示的是Capturing但端口不对去 Tools → Options → Connections 确认。顺手看一眼Allow remote computers to connect——跨机场景必须勾上勾上之后 Fiddler 会提示需要重启才生效很多人就是漏了这步重启。第二层JMeter 的代理配置到底有没有进去。最可靠的验证方式是看 JMeter 日志开头有没有相关输出或者在脚本里加一个查看结果树看响应头里有没有 Fiddler 附加的痕迹。更直接的办法故意把代理端口写成一个没人监听的端口比如 8899如果请求立刻报Connection refused说明代理配置确实生效了只是端口不对如果请求照样成功返回说明代理配置压根没被读到——那就回头检查是-H参数位置写错了还是改的是jmeter.properties而不是system.properties。第三层流量被 nonProxyHosts 悄悄放行了。这个最阴。表现是代理配置正确、端口正确、Fiddler 也在监听但就是没有会话。原因是被测地址命中了 Java 默认的非代理白名单。验证方法很简单把http.nonProxyHosts显式清空再试一次。第 1.3 节提过这个坑但它值得重复一遍因为它不属于配置错误配置本身是对的只是被另一条规则覆盖了从表面看不出来。第四层IPv6 与 DNS 解析顺序。极少数情况下JMeter 解析域名拿到的是 IPv6 地址而代理配置里写的是 IPv4 的回环连接行为会变得难以预测。把代理地址写成127.0.0.1而不是localhost能规避掉这一类玄学问题。4.2 只看到 CONNECT 隧道看不到任何明文这个现象非常有辨识度Fiddler 会话列表里出现一条CONNECT demo.internal.test:443状态是 200然后就没了展开也只有一个空壳。同时 JMeter 那边的响应可能是 200 也可能直接失败。这就是典型的TLS 握手在证书校验环节被拒。Fiddler 想解密但 JMeter 不认它的证书。回到第 3 章检查三件事信任库路径对不对、密码对不对、信任库里到底有没有那张 Fiddler 根证书。三样都对了还不行就要看 JMeter 启动时是不是被别的参数覆盖了——比如某些启动脚本里预置了javax.net.ssl.trustStore你命令行又传了一个最终谁生效取决于顺序很容易误判。还有一种情况容易被误认为证书问题Fiddler 的 HTTPS 解密没开。Tools → Options → HTTPS 里那两个勾选框Capture HTTPS CONNECTs、Decrypt HTTPS traffic只要有一个没勾你就会看到一堆 CONNECT 而没有明文。这个检查花不了十秒钟但很多人因为我明明记得勾了而跳过它最后绕了一大圈。4.3 抓到的请求和 JMeter 里看到的对不上这类问题最考验判断力因为现象是抓到了但内容不对劲。常见的三种走样压缩与编码。Fiddler 的 Inspectors 里如果看到一堆乱码先看响应头有没有Content-Encoding: gzip。JMeter 默认会带Accept-Encoding: gzip,deflateFiddler 抓到的是压缩后的原始字节需要在 Inspectors 里点一下解码按钮才能看明文。别看到乱码就以为请求体传错了。重定向与跟随。JMeter 的 HTTP 请求采样器默认勾选Follow Redirects一条逻辑上的请求在 Fiddler 里会展开成三条会话301 → 302 → 200。如果你按会话条数去数请求数必然对不上。看的时候认准第一条的 Request 和最后一条的 Response中间的跳转本身也是要检查的对象——有时候问题恰恰出在某个中间跳转把 Header 丢掉了。代理引入的额外头。走代理之后请求头和响应头里会多出一些原本不存在的东西比如Via、X-Forwarded-For之类。如果服务端有严格的 Header 白名单校验或者有基于来源 IP 的风控逻辑这些多出来的头可能直接导致行为变化。所以抓包环境验证通过不代表正式环境也通过这一点在第 6 章还会展开。4.4 一开 Fiddler压测数据就崩了这个问题属于操作正确但用错了场合。Fiddler 作为中间人每条请求都要建立两条 TCP 连接、做两次 TLS 加解密、做一次完整的内存缓冲和解析吞吐能力跟直连完全不在一个量级。你拿它去跑几百上千并发得到的 TPS 反映的是 Fiddler 的处理能力不是被测系统的。正确的用法是把抓包严格限定在功能调试阶段单线程、单次迭代、只跑你想查的那几条请求。等请求内容确认无误关掉代理、清掉配置再去做性能测试。如果确实需要在压测中观察流量特征应该换用抓包工具的网络层方案或者服务端侧的日志采样而不是让所有流量都从 Fiddler 走一遍。还有一种更隐蔽的影响某些服务的连接池行为会因为代理而改变。直连时 JMeter 可能复用连接走代理后连接建立与关闭的模式变了服务端的连接数统计、限流策略都可能被触发从而产生抓包时能复现、不抓包时复现不了的诡异问题。遇到这类现象先怀疑代理本身改变了行为别急着给被测系统提缺陷。5. 抓到之后怎么用从会话里把结论抠出来5.1 Inspectors 里到底该盯哪几块Fiddler 的 Inspectors 面板上下分栏上面是请求、下面是响应每一栏又有多个视图。实战中最常看的是这三个Raw 视图。它把实际在网络上传输的字节原样呈现包括请求行、所有 Header、空行、Body。判断JMeter 到底发了什么要看这个而不是 Headers 视图——Headers 视图会做美化偶尔会隐藏掉一些重复的头或者异常的换行。Headers 视图配合 WebForms。WebForms 会把application/x-www-form-urlencoded的 Body 拆成键值对展示对照参数特别方便。但要注意它对编码的处理中文参数如果被 URL 编码成了%E4%B8%ADWebForms 可能显示成解码后的样子看起来一切正常实际上服务端收到的是另一回事。所以要确认编码问题时必须回到 Raw 视图去看原始的百分号编码。TextView 与 HexView。前者看文本 Body后者看二进制。上传文件、图片、protobuf 这类请求TextView 里是乱码HexView 里才能确认字节数对不对。一个实用习惯在 Fiddler 里用CtrlF搜索关键字比在长列表里肉眼找快得多。查某个参数有没有发出去直接搜参数名。5.2 用 Composer 重放把变量一个个隔离出来看清楚了请求长什么样下一步是验证是不是这个变量导致的问题。Fiddler 的 Composer 面板可以把你选中的会话直接拖进去改一个参数重发一次对比响应差异。这个能力在排查参数编码、Header 缺失、签名错误时特别好用因为它完全绕开了 JMeter能快速确认问题到底出在脚本层还是服务端层。举一个实际场景。某次接口一直返回参数校验失败JMeter 的 View Results Tree 里看着参数都是对的。把请求拖进 Composer 一看发现表单里有中文参数被编码成了%25E4%25B8%25AD这种双重编码的形式——多了一层%25。原因出在脚本里先用函数做了一次编码采样器又勾了编码选项编了两次。这种问题不抓包根本看不出来因为 JMeter 界面上显示的是解码后的值。定位之后在采样器上取消编码选项就解决了。Composer 的另一个用法是做最小可复现请求把抓到的完整请求精简到只剩必要参数和必要 Header看服务端还认不认。这一步能帮你准确界定服务端到底依赖哪些字段反过来优化脚本里多余的配置。5.3 把差异做成对照组而不是凭感觉猜真正高效的排查方式不是看一眼觉得不对而是构造对照组。做法是保持其他一切不变只改一个变量跑两次把两次的 Fiddler 会话并排对比。Fiddler 自带会话对比功能选中两条会话右键 Compare Session会用 diff 的方式把请求头、请求体、响应头的差异高亮出来。这个功能在排查为什么这条成功那条失败时非常省时间——肉眼逐行看两个几百行的报文几乎必然会漏。对照组的变量可以是一个特定的 Header 加与不加、参数编码方式改与不改、Cookie 带与不带、请求方法 GET 与 POST。每次只动一个结论才干净。我见过太多人在一次实验里同时改了三处结果问题消失了也不知道是哪一处起的作用下次换个场景又踩一遍。6. 踩过才知道的几条经验6.1 端口冲突与回环监听的隐形门槛Fiddler 默认端口 8888 被占的情况比想象中常见——开发工具、其他调试代理、某些本地服务都可能占用它。表现是 Fiddler 启动时弹窗提示端口被占但很多人点掉之后继续用以为它自动换了个端口就行。实际上改端口之后 JMeter 侧的-P参数也得跟着改两头不一致的话表现就是连接被拒而错误信息又完全不提端口的事。换个端口不难在 Tools → Options → Connections 里改一个 8000 以上的空闲端口记得同步改 JMeter 侧配置。另一条经验是监听地址。Fiddler 的监听默认绑在所有网卡上Windows 第一次启动时通常会弹防火墙提示很多人习惯性点了取消或者直接关掉弹窗。后果是跨机场景下JMeter 所在的机器连不上 Fiddler 的端口。这种问题的迷惑性在于同机测试完全正常只有跨机才出问题很容易误判成网络不通。真遇到跨机连不上先在 JMeter 那台机器上用telnet fiddler-ip 8888试一下端口通不通一秒钟排除掉一大类可能。6.2 连接复用和 Keep-Alive 会让会话数对不上前面提过重定向会让会话数膨胀这里说反向的情况会话数比预期少。原因通常是连接复用。JMeter 的 HttpClient4 默认会保持连接一条 TCP 连接上可以跑多条请求。Fiddler 抓到的是连接层面的会话虽然它会把同一连接上的多条请求分别列出但如果你在数发了多少次时把连接建立次数当成了请求次数就会对不上。更需要注意的是另一种影响某些场景下你想验证服务端是否支持长连接结果因为走了代理代理自己的连接管理策略介入进来得到的结论并不可靠。判断连接复用相关问题最好在 Fiddler 的 Timeline 或 Statistics 视图里看时间线那里能看到每条请求在连接上的位置比单纯看条数直观得多。6.3 抓包环境和压测环境必须物理隔离这条是反复吃亏换来的。抓包时要改system.properties、要挂信任库、可能要临时忽略证书校验这些改动如果和正式压测共用一份配置早晚出事。最典型的事故是信任库调试期为了图方便把 Fiddler 根证书导进了机器上所有 Java 程序共用的信任库。事后忘了清理某天这套环境被拿去做别的事情等于给这台机器开了一个谁都能利用的信任后门。虽然内网环境风险有限但这类临时改动被固化的习惯本身就是隐患。我自己的做法是准备两套启动脚本jmeter-debug.sh里带上全部抓包参数jmeter-run.sh里干干净净什么都不带。切环境靠换脚本不靠改配置文件。配置类的东西一旦需要人记住现在是什么状态迟早会出错。另外抓包期间产生的.jtl结果文件不要直接拿去出报告。代理引入的延迟会污染响应时间指标样本量又小统计意义接近于零。抓包产出的价值是看清了请求内容不是测出了性能数字这两件事老老实实分开做。最后分享一个判断时机的小技巧当你在纠结要不要抓个包看看的时候答案基本都是要。因为猜请求内容这件事猜对的概率远低于你的直觉。抓一次五分钟比对着脚本逐行推演半小时靠谱得多。