
性能测试面试中有一个问题出现频率非常高“TPS 高响应时间也高并发数也高这三者到底是什么关系”很多人的第一反应是背公式TPS 并发数 / 响应时间。公式能背下来但换一个场景就不会用了。比如面试官追问“为什么并发数涨到 2000TPS 反而下降了”“为什么压测报告里 TPS 是 3000可生产环境只有 500”这时如果只靠公式很难答到点子上。这篇文章不绕圈子直接拆三件事TPS、并发数、响应时间之间的底层数学关系是什么用 JMeter 压测时怎么通过脚本设计和阶梯加压把这三个指标测准面试和实际报告中常见的“TPS 虚高”“并发数确认”“响应时间波动”问题怎么排查。全文以 JMeter 作为示例工具相关思路同样适用于 Locust、k6 等其他压测工具。没有给死板的标准答案只给能落地的操作路径。1. 性能测试核心指标速览先把几个容易混淆的名词理清。性能测试里TPS、QPS、RPS 经常混用但严格来说有区别。指标英文含义说明TPSTransactions Per Second每秒完成的事务数事务可以是一个完整业务动作比如“登录 查询 退出”QPSQueries Per Second每秒查询数多用于读接口表示每秒能处理的查询请求数量RPSRequests Per Second每秒请求数更偏向单次 HTTP 请求视为最简单的事务并发数Concurrency同一时刻正在系统中的请求/用户数指的是“in-flight”请求数不是“1 秒内发了多少请求”RTResponse Time响应时间从发送请求到收到完整响应的时间平均 RT 容易掩盖长尾问题TP99Top Percentile 9999% 请求的响应时间上限比平均 RT 更能体现极端延迟错误率Error Rate失败请求数 / 总请求数性能验收中通常会设阈值例如低于 0.1%一句话关系稳定状态下并发数约等于 TPS 乘以平均响应时间。用公式表达就是并发数 TPS × RT这个公式来自排队论中的 Littles Law是性能测试里最重要的底层关系。后面所有关于拐点、容量、资源利用率的分析都可以从这条公式出发。2. TPS、并发数、响应时间的底层关系2.1 从 Littles Law 看三者关系Littles Law 的核心思想是在一个稳定系统中系统里的人/请求/事务平均数量等于单位时间完成的数量乘以每个人/请求/事务在系统中停留的时间。对应到性能测试L λ × W其中L 表示系统中的并发请求数λ 表示到达速率也就是 TPSW 表示每个请求在系统中停留的时间也就是平均响应时间。改写一下就能得到最常见的三个推导TPS 并发数 / RT 并发数 TPS × RT RT 并发数 / TPS面试时先把这个公式讲清楚能证明你理解的是底层关系而不是背了一个“TPS 并发 / 响应时间”的简化写法。这里要特别注意公式里的 RT 是系统稳定状态下的平均响应时间包括请求排队等待时间、业务处理时间、网络传输时间。如果系统已经不稳定请求大量超时或者被拒绝公式的计量口径就会失真。2.2 未饱和、拐点与过饱和三个阶段压测过程中并发数从 1 慢慢加到 1000TPS 和响应时间的变化大致会经历三个阶段。第一阶段线性增长区。并发数很低系统资源充足每个请求都很快被处理。此时并发数增加TPS 几乎接近线性上升响应时间保持稳定。比如并发数从 10 涨到 50TPS 从 100 涨到 480平均 RT 还在 100ms 左右。这个阶段是系统的“舒适区”。第二阶段拐点区域。并发数继续增加系统资源接近饱和可能是 CPU 打满、数据库连接池不够、线程池队列堆积或者磁盘 IO 到了上限。响应时间开始明显上升TPS 的增速变缓最终触顶。触顶时的 TPS 就是这个系统在给定条件下的最大吞吐量。第三阶段过饱和区。并发数继续往上压队列堆积越来越严重响应时间急剧上升TPS 反而下降同时错误率开始增加。此时系统已经被压垮用户体验会迅速恶化。更直观一点把并发数作为 x 轴TPS 作为 y 轴曲线形状大致像一个左侧上升、顶点平滑、之后下降或持平的抛物线。这个顶点对应的并发数就是“最佳并发数”。而响应时间曲线则相反前期平缓拐点后急速上升几乎是一条前平后陡的曲线。2.3 为什么不能只看平均响应时间平均响应时间有一个很大的问题敏感性低。假设接口 TP99 是 800ms平均 RT 只有 150ms看起来不错。但实际请求分布可能是这样的90% 的请求在 100ms 内返回9% 的请求在 800ms 左右返回1% 的请求在 5s 后才返回。平均 RT 依然不高但真实用户体验已经比较差了。所以在压测中响应时间至少要记录四项平均 RT、TP50、TP90/TP95、TP99有条件再看 TP999。TPS 虚高的很多情况就是只用平均 RT 衡量性能忽略了长尾。2.4 面试时怎么组织答案面试官问“你解释一下 TPS、并发数、响应时间之间的关系”推荐按四步回答先定义三个指标不要跳定义讲关系写出 Littles Law 公式并发数 TPS × RT描述三个阶段未饱和、拐点、过饱和结合一次实际压测说明比如“我压测某个登录接口当并发数从 50 增到 200 时TPS 从 800 涨到 2000RT 从 50ms 涨到 120ms并发到 300 时 TPS 不升反降RT 到了 600ms所以系统的最佳并发在 250 左右”。这样回答既覆盖理论又有实际数据感比单纯背公式更有说服力。最后一步的数值需要根据你实际压测结果填写不要编造。3. 压测之前先回答三个问题启动 JMeter 之前先思考目标。没有目标的压测只是“把线程数调到 1000 点运行”跑出来的数字没有业务含义。3.1 目标并发数怎么定并发数不是拍脑袋出来的常见来源有三个历史运维数据参考上一年的峰值在线用户数、下单高峰期每分钟请求数业务预估新系统上线前产品给出未来半年的预期用户量和活动峰值容量模型推算如果无法直接拿并发数就先定 TPS 目标再结合 RT 期望倒推并发数。公式参考预估并发 高峰期每秒请求数 × 平均响应时间例如目标 TPS 是 2000期望 RT 是 100ms那么理论并发数就是 2000 × 0.1 200。3.2 目标 TPS 怎么定TPS 目标通常来自业务容量规划。比如电商大促场景订单系统每秒需要支撑 3000 笔订单创建那这个接口的 TPS 验收目标就是 3000。如果没有明确业务指标可以先用当前系统的历史峰值作为基线再乘以 1.2 到 1.5 的容量冗余系数。3.3 响应时间阈值怎么定响应时间阈值要按接口类型区分列表查询接口平均 RT 建议低于 200msTP99 建议低于 500ms下单/支付类接口平均 RT 可以到 300ms但 TP99 不能超过 1s图片上传、批量导出、大文件下载不追求单请求 RT更关注吞吐量和稳定性。这些经验值不是绝对的但能帮助你在压测前建立起可量化的判断标准。4. 用 JMeter 设计性能测试脚本4.1 JMeter 测试计划的基本结构一个标准的 JMeter 测试计划至少包含以下部分组件作用是否必须线程组设置并发数、Ramp-Up 时间、循环次数必须采样器发起 HTTP、JDBC、JMS 等真实请求必须逻辑控制器控制请求执行顺序、循环、条件分支按需配置元件参数化、CSV 数据、HTTP 默认值按需断言判断请求是否成功防止错误请求被计算进 TPS建议必须监听器聚合报告、图形结果、查看结果树调试时用定时器模拟思考时间、控制请求频率按需这里要多说一句如果压测脚本里没有断言JMeter 会把“连接超时的请求”和“返回了 HTTP 500 的请求”也当作“完成了一次请求”计入统计结果。TPS 虚高的重要来源之一就是断言缺失。4.2 线程组并发设置思路JMeter 的线程组里有三个关键值线程数代表并发用户数Ramp-Up 时间所有线程启动完成所需的时间循环次数每个线程执行的次数。在压测初期建议把循环次数设置为“永远”并在线程组下方组合一个“持续时间”这样可以控制压测时长避免因循环次数估算错误导致测试时间不可控。线程组设置示例线程数 200 Ramp-Up时间(秒) 60 循环次数 永远 持续时间(秒) 600Ramp-Up 时间要合理设置。如果目标是 200 并发Ramp-Up 设成 1 秒相当于 1 秒内瞬间拉满 200 个线程这对被测系统和服务端资源都会产生较大的瞬时冲击不利于观察平滑的性能曲线。一般建议 Ramp-Up 时间不少于线程数的 1/5实际以目标系统表现来调整。4.3 参数化与断言避免 TPS 虚高压测脚本不参数化很容易出现缓存型和幂等型虚高。举个例子压测一个订单查询接口所有线程都用同一个用户 ID 去查。第一次查询后Redis 缓存已经生效后续大量请求直接命中缓存TPS 自然很高。但生产环境的用户分布远不是这样这个 TPS 不能代表真实容量。参数化常用组件CSV Data Set Config从文件读取测试数据每个线程消耗一行JDBC Connection Configuration 和 JDBC Request直接从数据库查询参数User Defined Variables静态变量适合固定 token 和基础路径正则表达式提取器 / JSON 提取器从上一请求响应中提取动态值。断言至少需要覆盖 HTTP 状态码和业务返回码。对于返回 JSON 的接口推荐用 JSON 断言直接校验业务状态字段。一个压测脚本的好坏不是看请求多不多而是看是否还原了生产请求的真实形态。5. 功能测试与效果验证5.1 先单线程跑通脚本压测的第一条铁律先小规模跑通再大规模加压。用 1 个线程、循环 1 次跑一遍测试计划打开“查看结果树”检查请求是否返回 200响应内容是否符合业务预期提取的 token、订单号等参数是否成功传递给后续请求JMeter 日志是否报错。这个阶段不关注性能数字只关注脚本正确性。5.2 阶梯加压找到线程数拐点找到拐点最快的方法是阶梯加压。可以手动分多轮测试也可以使用 JMeter 插件的 Stepping Thread Group 或 Concurrency Thread Group 来自动加负载。手动阶梯压测的参考方案第 1 轮线程数 20持续压 5 分钟 第 2 轮线程数 50持续压 5 分钟 第 3 轮线程数 100持续压 5 分钟 第 4 轮线程数 200持续压 5 分钟 第 5 轮线程数 400持续压 5 分钟每轮结束后记录TPS、平均 RT、TP90、TP99、错误率、应用服务器 CPU、内存。当出现的组合是“TPS 不再增长 / 增长非常缓慢RT 明显上升错误率开始出现”上一轮的并发数就是接近拐点的值。5.3 压测观测表建议用一张表记录各轮结果方便后续做容量判断压测轮次并发数TPS平均 RTTP99错误率应用CPU应用内存结论第 1 轮2035053ms89ms0%25%1.2G系统轻松第 2 轮5082061ms110ms0%45%1.4G线性上升第 3 轮100151066ms130ms0%68%1.6G接近拐点第 4 轮2001620185ms420ms0.5%85%1.9G已过拐点这里面的数字只是示例真实压测要以你运行的结果为准。表格的价值在于展示“从哪里开始收集数据以及如何判断结论”。5.4 判断系统是否达标判断系统是否达标需要把压测结果和验收标准对比通过 TPS ≥ 目标TPS 且 TP99 ≤ 目标TP99 且 错误率 ≤ 阈值只有 TPS 达标但响应时间已经超过 SLA依然不能算通过。性能和稳定是并行的两项要求。6. 命令行批量压测与 HTML 报告JMeter 的 GUI 模式只适合脚本调试和看曲线正式压测推荐使用非 GUI 模式。原因很简单GUI 本身会消耗 CPU 和内存会影响压测结果的准确性。尤其在高并发下JMeter 自带的图形监听器会成为本地瓶颈。非 GUI 压测命令如下# 先切换到 JMeter 的 bin 目录 cd /opt/jmeter/bin # 执行压测保存 JTL 原始结果并生成 HTML 报告 ./jmeter -n -t /opt/jmeter/test/order_api.jmx \ -l /opt/jmeter/result/order_api_20250301.jtl \ -e -o /opt/jmeter/result/html_report_20250301 \ -j /opt/jmeter/result/log/order_api_20250301.log参数说明-n表示非 GUI 模式-t指定测试计划文件-l指定结果文件JTL 是 CSV 格式的性能数据原始记录-e表示压测结束后自动生成 HTML 报告-o指定 HTML 报告输出目录-j指定 JMeter 运行日志文件。压测结束后HTML 报告里会包含聚合图、响应时间分布、TPS 趋势、错误率等几十种图表面试或汇报时可以优先看这几张Throughput 图、Response Time Percentiles 图、Latency over Time 图、Errors 图。批量压测的思路也可以描述为把一组测试计划文件放到一个目录下用脚本循环执行每次输出带时间戳的结果文件后续再做回归对比。这本质上就是性能测试领域的“批量任务”。7. 接口观察与压测中的资源监控压测时不仅要看 JMeter 的聚合报告还要观察被测系统自身的资源状态。一个常见的误区是JMeter 显示 TPS 已经 2000 了应用服务器的 CPU 却只有 10%于是得出“系统性能很好”的结论。但真实原因很可能是压测客户端线程池已经耗尽或者网络带宽被打满请求根本没有到达应用服务器。这时候你需要判断压力是否真打到目标上。观察资源占用的几个方向被测应用所在节点的 CPU 使用率、Load Average、内存使用率Java 进程的 GC 日志尤其是 Full GC 频率数据库的连接池使用情况、慢查询数Redis 所在的缓存节点命中率和响应时间网络层带宽、TCP 连接数、TIME_WAIT 数量。JMeter 可以通过 PerfMon 插件配合 ServerAgent 来监控远程主机资源但更推荐优先使用云监控平台或运维自带的监控面板数据源更准确也能减少插件本身造成的额外开销。压测的目的是发现哪一层先成为瓶颈而不是单纯为了跑出一个高分数字。很多性能问题并不是应用代码的问题而是数据库慢查询、缓存穿透、连接池不够、G1 GC 参数不合理等原因造成的。8. 常见问题TPS 虚高与并发数确认8.1 TPS 虚高的排查思路面试中“TPS 虚高”是一个高频追问点。所谓虚高是指压测得到的 TPS 远高于真实系统容量换一个测试方法或真实流量进来就露馅。常见原因如下问题现象可能原因排查方式解决方案TPS 很高但业务上总请求量对不上断言缺失错误请求被统计为成功查看聚合报告错误率对比响应数据增加响应断言和 JSON 业务断言并发线程越多TPS 越线性增长RT 也不变压测数据不合理命中了缓存检查参数化数据是否单一Redis 命中率CSV 参数化多账号多数据压测结果不稳定重启后数字差异大测试环境缓存预热不足先空跑预热再正式测试增加预热脚本先请求一批关键接口请求全部走短连接频繁三次握手网络层或框架配置不当对比长连接压测结果按生产实际配置连接池客户端 JMeter 本地 CPU 100%TPS 上不去客户端成为瓶颈观察 JMeter 所在机器资源使用非 GUI 模式必要时分布式压测压测只跑了 30 秒数据还没稳定压测时长太短线程仍在 Ramp-Up看 TPS 曲线是否稳定加长持续时长观察稳定段数据排查 TPS 虚高时一个有效的方法是做数据交叉验证成功的业务请求数 压测时长内的总事务数 - 错误事务数 TPS 成功的业务请求数 / 压测时长如果这个值和 JMeter 报告里的 TPS 明显不一致说明统计口径出了问题。8.2 如何确认系统的并发数面试题里常出现的问法是“JMeter 压测怎么确认系统的并发数”。这个问题要从两个层面去回答。第一个层面是业务层并发数目标从历史峰值和容量规划来。第二个层面是技术层通过阶梯加压寻找拐点。拐点之前的最大并发数就是系统在当前硬件和配置下的相对合理并发数。操作步骤可以概括为五步单线程跑通脚本从低并发开始每次递增 20 到 50 个线程保持同一压力 5 到 10 分钟收集稳定段数据记录 TPS、RT 和错误率的变化找到 TPS 触顶或 RT 开始陡增的点那个点对应的并发数就是参考值。这里要留意同一个系统在不同测试数据、不同接口组合、不同时间段下最佳并发数可能完全不同。真正要回答的是“在什么条件下确认的并发数”而不是一个孤立数字。8.3 响应时间波动大的原因响应时间波动大通常不是单一因素。常见的排查顺序看是否有突发 GC特别是一次性大对象导致 Full GC看慢 SQL 是不是偶发性的比如数据量增长、索引失效看线程池队列是否在高峰期被打满看网络代理、网关、负载均衡是否有超时重试看压测机本身是否在波动比如 CPU 被其他进程抢占。建议在看板中把响应时间曲线按 TP50、TP90、TP99 三条线绘制如果 TP99 波动明显而 TP50 平稳大概率是长尾请求或资源竞争问题如果三条线一起波动更可能是整体资源出现了周期性瓶颈。9. 性能测试最佳实践与合规边界9.1 压测前需要确认的边界性能测试通常需要向目标系统发起大量请求如果目标环境是正式生产环境必须重点关注授权和风险。压测前应取得测试负责人、业务运维方或系统所有者的明确授权推荐优先使用专用测试环境或准生产环境如果必须压测生产环境应选择低峰期设置压测最大并发上限和自动熔断机制避免影响真实用户测试数据应脱敏尤其是涉及用户手机号、身份证、登录态等敏感字段不对未授权的系统、第三方服务、云厂商共享资源发起压测。这一点不只是为了合规也是性能测试从业者的基本职业边界。9.2 工程化压测的建议成熟的性能测试工作流应该具备可重复性。推荐的工程化方式将 JMeter 脚本纳入 Git 管理和代码一样保存版本记录每个版本的压测结果单独归档命名建议带上项目、接口、日期、版本号压测前先跑一遍脚本正确性验证再进入正式压测同一次压测至少保留原始 JTL、HTML 报告、压测日志、环境配置说明四类文件每次回归对比时使用相同的线程数、相同的数据量、相同的持续时长保证结果可比接口服务和具体被测接口的业务参数发生变化时及时更新脚本和基线结果。压测本身不难难的是让结果可信、可回溯、可对比。9.3 AI 辅助性能测试脚本的思路近年来已经有大量 AI 工具可以帮助生成 JMeter 脚本、JSR223 Groovy 断言和性能分析报告。实际使用时建议这样分工用 AI 生成脚本骨架快速搭建线程组和 HTTP 请求用 AI 编写常见 Groovy 断言代码但仍需人工审查用 AI 解释聚合报告中的异常曲线从“结果描述”反推可能原因不要直接把 AI 生成的脚本用于高并发压测尤其不要忽略参数化、断言和测试数据设计。AI 能提升写脚本的效率但性能测试的分析深度还是依赖测试人员对业务和系统架构的理解。10. 总结与下一步回到标题问题TPS、并发数、响应时间三者的底层关系可以浓缩成一句话并发数是压进系统的负载TPS 是系统在单位时间内实际完成的处理量响应时间则是每个请求在系统中停留的“成本代价”。三者通过并发数 TPS × RT这条排队论公式串联在一起。系统未饱和时并发增加带动 TPS 增长RT 保持平稳系统过载后RT 会快速上涨TPS 反而下降。性能测试的核心工作就是找到这个拐点并用可量化的数据描述系统容量。如果你正在准备性能测试相关工作建议下一步直接动手做一轮阶梯压测。选一个你们系统里最简单的只读接口设计一套带断言和参数化的 JMeter 脚本从 10 并发开始压到 200 并发记录每一轮的 TPS、TP99 和错误率。你会发现公式背得再熟都不如亲眼看到拐点的过程记忆深刻。