☰
性能测试核心术语与计算公式:TPS、QPS、并发数及利特尔法则详解
2026/10/1 18:36:07 网站建设 项目流程

说到性能测试,很多人第一反应是“压测”,第二反应是“调JMeter参数”。但真正容易翻车的地方,往往是开头那一堆术语和计算。TPS、QPS、并发数、响应时间、P95、错误率……这些词在开发、产品、领导的嘴里经常不是同一个意思。一份报告发出去,先吵起来的往往不是系统瓶颈在哪,而是“你测的这个数到底代不代表正常情况”。

这篇文章我想把性能测试里最常用的术语和计算方式一次性讲透,包括每个术语背后对应的业务问题、计算公式、典型坑位,最后用一个登录接口的完整案例,把从负载模型到指标判读的链路走一遍。适合刚接触性能测试的测试工程师,也适合正在准备性能测试面试的同学。

1. 性能测试术语的底层框架:五种测试类型到底在回答什么问题

如果你把性能测试当成一个总称,很容易把基准测试、负载测试、压力测试、容量测试、稳定性测试全部混为一谈。面试时最常出现的翻车现场是:“我做过性能测试。”“具体哪种?”“就是压测啊。”实际上,这几种测试回答的是完全不同的问题,选择哪一种,取决于你当前的目的是什么。

1.1 基准测试、负载测试、压力测试

基准测试(Benchmark Testing)的目标是给系统打一个基线刻度。比如同一套硬件环境,用固定的脚本、固定的数据量跑一次,得到一组TPS、响应时间、资源占用数据,作为后续版本对比的参照。有了基线,你才能在新版本上线前回答“这次改造到底是让性能变好了还是变差了”。它是性能测试里最容易被忽略但实际价值很高的一类,因为没有基线,所有后续优化都没有对比起点。

负载测试(Load Testing)模拟的是真实业务负载。它的核心问题不是“极限在哪”,而是“在预期的业务量下,系统能不能稳稳达标”。比如业务方说高峰期每秒会来50个下单请求,那你就设计50 TPS的负载跑一段时间,看响应时间、错误率、资源占用是否在约定范围内。负载测试的重点是贴近真实,脚本里通常需要加入用户思考时间、不同接口的混合比例。

压力测试(Stress Testing)则是持续加压,直到超过预期负载,找到系统的极限拐点和崩溃行为。它回答的是“系统最多能扛多少”“扛不住的时候表现是什么”。加压方式常见的有两种:一种是把并发线程数不断往上加,一种是单线程的循环次数不断缩短。压力测试的产出不是“达标”,而是“系统在哪个点开始垮”,以及“垮的方式是优雅降级还是直接不可用”。

1.2 容量测试、稳定性测试与实测边界

容量测试(Capacity Testing)和压力测试经常被混用,但侧重点不同。压力测试偏重“打崩它看表现”,容量测试偏重“不崩的前提下最多能装多少”。容量测试通常和容量规划绑定,回答的是“当前集群在指标达标的前提下,最多能支撑多少日活、多少笔订单”,它需要结合未来的增长预期,给出扩容建议。

稳定性测试(Soak Testing / Endurance Testing)是专门抓“慢性病”的。把系统放在正常或略高的负载下长时间运行,短则8小时,长则72小时,观察TPS是否随时间推移逐渐下降、内存是否持续上涨、数据库连接池是否膨胀、临时文件是否堆积。内存泄漏和连接池耗尽这类问题,只跑20分钟压测是看不出来的,必须靠小时级运行才能暴露。

为了让大家少踩“类型混乱”的坑,我把五类测试的实际区别整理成一张表:

测试类型核心问题典型负载设计主要产出
基准测试这套环境在X负载下是多少固定脚本、固定数据量基线数据、版本对比
负载测试X负载下能否达标按预期业务负载模拟是否达标结论
压力测试极限在哪、超出后表现如何逐级加压直到崩溃拐点、瓶颈定位
容量测试不崩的前提下能装多少探测性加压并验证指标容量上限、扩容建议
稳定性测试长时间运行会不会衰减正常负载跑数小时以上泄漏与慢增长风险

实际项目里这五类的边界经常是模糊的,负载测试压着压着就可能变成压力测试。但写报告时必须把类型定义写清楚,否则别人会问“你测的是预期负载还是极限负载”,这个问题答不上来,报告的可信度会大打折扣。

2. 响应时间:从“用户觉得慢”到“数据说慢”

响应时间(Response Time)是性能测试里最直观的术语,也是被误读最多的一个。很多人以为响应时间就是后端处理时间,其实用户感受到的响应时间是一条完整链路上的累计结果,从点击按钮开始,客户端组包、网络上行、接入层、业务处理、下游依赖、网络下行,最后到浏览器解析渲染,每个环节都在消耗时间。

2.1 一次请求的响应时间是怎么组成的

压测工具测出来的响应时间,通常是“从发送请求到接收完成最后一个字节”的时间,它天然包含网络开销。所以做性能比对时,先要确认压测机和被测系统的网络拓扑。同一个接口,压测机在机房内网直连应用,平均响应时间可能只有50毫秒;用户从办公室跨运营商访问,可能是500毫秒。这500毫秒里,应用本身没变慢,变的是网络路径。

细分下来,响应时间大致可以分为几个环节:

  • 客户端请求组包与发送时间
  • 网络上行传输时间
  • 接入层处理时间(网关、负载均衡、Web容器)
  • 应用业务逻辑处理时间(含中间件、框架层)
  • 下游依赖时间(数据库、缓存、第三方接口、消息队列)
  • 网络下行传输时间
  • 客户端解析与渲染时间

前六项是后端压测通常覆盖的范围,第七项属于前端性能,压测工具一般管不到。排查响应时间变慢时,如果只看总耗时,等于只知道“慢了”但不知道“在哪慢的”。正确做法是先分段看:是网关层耗时增加,还是数据库慢了,还是第三方接口拖了后腿。线上APM工具(SkyWalking、Pinpoint这类)可以把调用链每一跳的时间拆出来,压测期间建议同步启动。

2.2 平均值会骗人:中位数、P90/P95/P99

压测报告里最常见的一句话是“平均响应时间200毫秒,表现良好”。但平均值在性能数据里经常具有欺骗性。我举一个很极端的例子:100个请求里,有1个请求耗时10秒,其余99个都是0.1秒,平均值是(10 + 99×0.1) / 100 = 0.199秒,看着非常漂亮。但在真实用户里,有1%的人体验是10秒,这已经足够引发投诉了。

所以可靠的性能分析必须看分布,而不是只看平均值。百分位数的计算方式很简单:把所有样本的响应时间从小到大排序,排在95%位置的那个值就是P95,意味着95%的请求耗时都小于这个值。常用的几个百分位指标如下:

指标含义典型用途
Median(中位数)50%请求小于该值看整体分布的中心
P9090%请求小于该值日常监控常用
P9595%请求小于该值对外承诺的常见标准
P9999%请求小于该值捕捉长尾用户体感
Max最大耗时异常点定位

我给团队定的一个基本规则是:监控和报告里至少同时给出中位数、P95、P99三列,缺一不可。平均值可以保留,但它只用来做趋势参考,不能作为达标的唯一依据。面试时如果被问到“你们性能指标怎么定的”,能说出“基于用户分布看P95而不是只看平均值”,会明显加分。

2.3 2-5-10法则和业务预期的校准

2-5-10法则是一个流传很广的经验判断:2秒以内体验良好,2到5秒可以接受,5到10秒比较糟糕,超过10秒用户基本流失。这个标准在传统页面型业务里仍然有一定参考价值,但不要把它直接抄到所有业务上。

不同业务的响应时间预期差异非常大。登录认证类接口,用户心理预期是“点了就要有反应”,P95压到1.5秒以内都不算快;即时消息收发、扫码支付这类交互,目标通常是毫秒级;而BI报表、批量导入这类任务,跑几十秒甚至几分钟都正常,关键是给用户一个进度反馈。性能目标应该由产品和技术一起根据用户行为定义,而不是拍脑袋套一个固定值。

3. 吞吐量、TPS与QPS:三个名称背后的换算逻辑

吞吐量是衡量系统处理能力的关键指标,但在不同人口里有三种叫法:TPS、QPS、RPS。这三个词看着像,实际口径差别很大,不对齐就比数据,基本等于鸡同鸭讲。

3.1 请求、事务、查询的粒度差异

先明确三个概念。请求(Request)是客户端发起的一次HTTP调用或RPC调用。查询(Query)在数据库语境里是一条SQL,在互联网语境里往往被泛化成“一次读操作”。事务(Transaction)是一个完整业务动作的集合,一个事务可能包含多个请求或查询。

以“下单”为例:用户在客户端点一次“提交订单”,背后可能触发查询商品详情(1次HTTP)、提交订单(1次HTTP)、轮询支付结果(2次HTTP)。如果压测脚本把整个下单流程定义成一个事务控制器,那么TPS等于每秒完成的下单笔数;如果脚本只是直打HTTP请求,没有事务控制器,JMeter报表里的样本会记录4次请求。同样是“性能不错”的结论,前者TPS是100,后者RPS是400,两边拿数字一对就会吵架。

我在出报告时会明确标注“TPS按事务统计”或“RPS按请求统计”,并写明脚本里是否用了事务控制器。这个动作花不了半分钟,但能省掉后面大量的解释成本。

3.2 TPS与QPS的计算方式和采样窗口

计算公式本身不难:

TPS = 完成事务总数 / 有效测试时长
QPS或RPS = 总请求数 / 有效测试时长

真正的坑在“有效测试时长”怎么界定。压测刚开始时,线程从0逐级启动,前几秒的样本是“预热期”,数据不具备代表性。如果从第1秒的数据就开始统计,TPS会被明显拉低,指标判断就会失真。

我写JMeter压测命令时,习惯的做法是用时长控制器设定运行时间(比如8分钟),然后取中间稳定段的5分钟数据来算。JMeter聚合报告里的Throughput列,本身是取样时间窗内的平均速率,单位是“样本数/秒”。注意看样本数对应的到底是什么:如果脚本里只有HTTP Sampler,它就是RPS;如果套了事务控制器,它才是TPS。

3.3 从TPS反推容量规划:一道30秒的上限题

吞吐量的计算不仅能判断当前性能,还能反过来做容量规划。假设业务高峰期每秒要处理3000笔业务,每笔业务平均需要经过2个内部接口调用,那下游API的QPS至少要按6000来规划。很多容量事故的根因就在于:上游TPS达标了,下游接口的QPS规划却少算了一个“调用倍数”。

还有一种常见场景是扩容评估。现有集群在峰值时TPS为5000,每台机器的单机TPS上限是1500,那么至少需要4台机器才能扛住当前峰值,如果预留30%的冗余量,就是5台。这个计算逻辑不复杂,但它能直接指导“到底要不要扩容、扩几台”,是性能测试结果落地到运维侧最重要的产出。

4. 并发用户数:从日活到并发数的三层估算法

并发用户数是性能测试里最容易产生分歧的术语。它不是一个固定的物理量,而是和业务场景强相关的统计量。很多人一张嘴就是“我们系统有10万用户”,但压测时不可能按10万线程去压,因为真实业务里根本不会有10万人同时点同一个按钮。

4.1 四类“人数”别混在一起

先把概念拆开。注册用户是存量,代表业务规模;活跃用户是有行为的人群,通常按日活(DAU)或周活(WAU)统计;在线用户是当前挂着但可能没有操作的人群;并发用户才是真正在同一时刻发起请求的人群。四者的数量级差距可以非常大。

举一个实际例子:一个10万日活的App,晚间高峰在线用户可能1万左右,但真正在1秒内并发访问某个核心接口的,可能只有几百人。把在线用户数直接填到JMeter线程组里,相当于把负载测试直接变成了压力测试,测出来的数据远高于真实业务负载,得出的结论会过度悲观。

4.2 平均并发公式与峰值修正

估算并发用户数有一个常用的工程公式:

平均并发用户数 C = n × L / T

其中n是考察时间段内的独立用户数,L是每个用户的平均会话时长(秒),T是考察时间段的总秒数。以一个业务系统为例:日活5万,用户平均每次会话时长5分钟,也就是300秒,访问主要集中在每天8:00到22:00共14小时,即50400秒。平均并发 = 50000 × 300 / 50400 ≈ 298人。

但平均并发只回答了“中间水平”,压测更关心峰值。高峰小时段(比如20:00到21:00)的并发通常可以达到平均并发的2到3倍,按2.5倍估算就是745人左右。这个“峰值系数”最理想的数据来源是线上真实监控,如果没有线上数据,可以用经验公式 Cmax ≈ C + 3√C 做估算,它假设并发分布接近正态,估算的是95%置信上限。代入上面的例子,298 + 3×17.26 ≈ 350,比2.5倍系数算法保守一些,也更适合波动不大的常规业务。

在使用这些公式时需要特别说明:它们是工程估算,不是精确推导。估算出来的并发数必须经过压测验证和线上监控校准,才能作为负载模型的输入。

4.3 思考时间:线程数不是用户数

真实用户操作时,点完一个按钮后大概率会停几秒去读内容、填表单、犹豫一下。这个停顿就是思考时间(Think Time)。压测时如果不设置思考时间,虚拟用户会以最快速度连续发请求,测的是系统的极限上限,适合找瓶颈,但不适合评估真实业务负载。

线程数相同的情况下,思考时间从0改成3秒,TPS可能直接掉一半以上。这就是为什么“同一套脚本、同样的线程数”,在不同人手里会得出完全不同结论。负载测试的脚本里,应该按业务节奏添加定时器。JMeter里可以用Constant Timer固定等待,也可以用Uniform Random Timer模拟更自然的随机间隔,让请求节奏更接近真实用户。

5. 利特尔法则:并发、响应时间、吞吐量怎么互相锁死

如果说前面那些公式是单独的指标计算,那利特尔法则(Little's Law)就是把这些指标串起来的核心定律。它来自排队论,但实际应用中完全不需要数学背景。公式很简单:

N = TPS × RT

其中N是系统内平均并发请求数,TPS是吞吐量,RT是平均响应时间。这个公式在稳定系统状态下是严格成立的,用来做现场口算非常顺手。

5.1 N = TPS × RT,两个计算示例

先看一个正常示例。压测结果显示TPS为300,平均响应时间250毫秒,即0.25秒。系统内同时存在的请求数N = 300 × 0.25 = 75。意思是在这个负载下,同一时刻系统里大约有75个请求正在被处理或排队。如果压测线程数恰好是75,那每个线程基本都有活干;如果线程数是150,就会有一半线程在排队等待。

再看一个瓶颈示例。压测线程数设为100,平均响应时间1秒。按理想情况,系统最多能处理的TPS是100/1 = 100。但实际测出来TPS只有40,那就说明并发线程根本不是瓶颈,而是系统某个环节消化不了这么多请求,比如数据库连接池满了、下游接口响应慢、GC频繁、存在锁竞争。这时候继续加线程只会让响应时间变得更长,TPS基本不会涨。

5.2 压测现场的口算体检法

压测过程中,我会一边看实时TPS和平均RT,一边口算N = TPS × RT,然后拿N和当前线程数对比:

  • 如果N明显小于线程数,说明大量请求在排队等待,系统正在逼近饱和状态
  • 如果N接近甚至大于线程数,说明每个线程都很忙,继续加压只会把RT拉高
  • 如果TPS平稳但RT一直在涨,说明系统在“以牺牲响应时间维持吞吐量”,用户体感已经变差,这是需要警惕的信号

这个方法不需要额外工具,比只盯着TPS一条曲线有用得多。压测过程中一旦发现RT开始陡增,基本可以判断拐点快到了,这时候再决定要不要继续加压探索极限。

5.3 用利特尔法则确定初始线程数

利特尔法则还有一个很实用的反向用法:确定压测初始线程数。假设目标TPS是100,预期平均响应时间是0.5秒,那么理论并发数N = 100 × 0.5 = 50。设置压测线程数时,我一般取理论并发的1.5倍起步,也就是75个线程,然后逐级加压。

这样做的好处是,既不会因为线程数太少导致TPS测不出来,也不会一上来就用很大的线程数把系统直接压垮,节省试错时间。加压的梯度一般是理论并发数的0.5倍、1倍、1.5倍、2倍,每档跑5到10分钟,观察TPS和百分位响应时间的变化趋势。

6. 一次登录场景的完整计算演练:从负载模型到JMeter验证

前面讲了一堆术语和公式,下面用一个完整的登录接口案例,把从业务参数到压测执行的链路串起来。这也是面试里经常被问的“给你一个接口,你怎么做性能测试”的标准思考过程。

6.1 从业务参数算出目标负载

需求描述如下:登录接口日调用量20万次,高峰集中在2小时内,要求P95响应时间小于2秒,错误率小于0.1%。

先算高峰平均TPS:200000 / 7200 ≈ 27.8。考虑到业务波动,取2.5的峰值系数,目标TPS定为70。假设平均响应时间0.5秒,根据利特尔法则,理论并发数N = 70 × 0.5 = 35。初始压测线程数取理论并发的1.5倍,约52,实际设置时就取整数50。

这是一个完整的计算链路:业务量 → 单接口TPS → 乘以峰值系数 → 得到目标TPS → 结合预期RT → 得到并发线程数。每一步都有依据,别人问起来你也能讲清楚数字是怎么来的。

6.2 用JMeter跑一轮并解读报表

JMeter压测的推荐姿势是命令行模式,不要开着GUI压。GUI用于调试脚本可以,但正式压测时,GUI本身会抢占压测机的CPU和内存,干扰结果。基本命令如下:

jmeter -n -t login_test.jmx -l result.jtl -e -o report_dir

其中-n表示非GUI模式,-l保存原始样本数据,-e和-o生成HTML报告。脚本里如果只放一个HTTP请求,Throughput列就是RPS;如果套了事务控制器包住整个登录流程,它才是真正意义上的TPS。这一点我在前面已经强调过,实际读报告时一定先确认。

假设加压结果如下:

并发数TPSP95响应时间错误率判断
50481.8秒0.05%基本达标
70662.1秒0.2%错误率超限
100683.8秒1.2%拐点出现

从这组数据能明显看到,系统在70并发附近已经到达吞吐量上限。继续加压后,TPS基本不涨,P95响应时间和错误率快速飙升,说明瓶颈已经出现。此时加线程无济于事,应该去查数据库连接池、下游依赖或者锁竞争,而不是继续盲目加压。

另外补充一点:线程数加到50以后,如果发现TPS增长开始放缓,不要急着下结论,先确认压测机本身没有先到瓶颈。压测机CPU超过70%、内存不足、带宽打满,都会导致结果失真。Linux下还要注意文件描述符上限和可用端口数,高并发连接时这两个参数经常成为隐性限制。

6.3 压测机自身的口径校验

“测出来的不是系统瓶颈,而是压测机瓶颈”是性能测试里最常见的低级翻车。分布式压测时,一定要检查所有负载机的负载是否均衡、时钟是否一致、网络是否在同一内网。单机压测时,先看压测机资源占用是否过低或过高:过低说明压不上去,过高说明结果不可信。

我给团队定的标准是:压测机CPU和内存占用尽量控制在70%以下,带宽余量至少留30%。否则任何关于“系统上限”的结论都要先打一个问号。这个校验动作放在压测开始前做,比结束之后发现数据无效再重测要省时间得多。

7. 性能测试计算中三个最容易翻车的口径问题

最后集中盘点三个最容易让整个报告翻车的口径问题。这些不是冷门知识,而是日常实战里反复出现的坑,每次踩完都想抽自己一下那种。

7.1 错误率的分子分母与错误分类

错误率的基础公式是:失败样本数 / 总样本数。但“失败”的定义如果不拆开,问题很难定位。至少要把错误分成三类:网络层错误(连接失败、超时)、协议层错误(HTTP 5xx)、业务层错误(HTTP 200但响应体里的业务code是失败)。

压测工具默认只认协议层错误,HTTP 200就算成功。如果业务系统用“HTTP 200 + 业务code=500”的方式报错,工具不会自动统计,需要自己在断言脚本里处理。所以报告里如果只说“Error%是0.1%”,但不说明错误类型构成,排查的人会非常痛苦。“我见过超过0.1%错误率时,先把jtl或日志拉出来看是哪种错误,再判断是环境问题还是系统问题。”这句话写在面试里,比直接背定义要更有说服力。

7.2 资源利用率的“核”与连接池

CPU使用率要看整体和单核两层。8核机器整体CPU 40%,但某个核已经冲到100%,这就是典型的单线程瓶颈,可能是某个热点方法或者GC线程抢占了单核。只看整体CPU会漏掉这类问题。

内存要看趋势而不是单点。JVM堆内、堆外的内存使用量是否随着测试时间持续上涨,才是判断有没有泄漏的依据。单纯报一个“内存占用80%”没有意义,要看它是一条平稳线还是向上爬的斜线。

数据库连接池、中间件线程池是否打满,往往比CPU和内存更能说明瓶颈。一个接口TPS上不去,很多时候不是机器算力不够,而是数据库连接池只有20个连接,请求全在连接池入口排队。

7.3 带宽估算:压测前先算够不够

压测前可以先做一道算术题:目标TPS是1000,响应体平均大小20KB,单向带宽需求大约是1000 × 20 × 8 / 1000 = 160Mbps。这还没算请求体、TCP/IP头、重传开销。如果压测机网卡只有100Mbps,目标TPS根本压不上去。遇到TPS上不去时,先看是不是网络链路先满了,再排查应用层。

带宽估算不仅适用于压测机,也适用于生产容量规划。尤其是涉及文件上传、下载、大报文XML/JSON的接口,带宽经常被忽略,最后用户端表现为“响应时间慢、请求超时”,但应用服务器CPU和内存一点都不高,查半天才发现是带宽打满。

最后分享一个我自己的习惯:每次性能测试开始前,我会先把报告模板里的指标口径写清楚,包括“并发用户数指的是什么并发”“TPS按事务还是按请求算”“P95的采样窗口从第几秒开始算”。因为开发、产品、领导对同一句话的理解经常不同,口径不统一的时候,测出来的数据再准也会被讨论成各说各话。这套术语和计算,本质上是在帮所有人对齐认知,而不是制造数字。下次压测前,你也可以先试试把口径写下来,再动手跑脚本。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询