先说一个很多人问过的问题:功能测试明明已经把系统测"对"了,为什么还要单独做性能测试?
答案藏在"对"和"好"的差别里。想象一下五菱和法拉利:从功能上说,它们都有四个轮子、一个方向盘,能坐人,能往前开,挡风玻璃能遮风挡雨——功能完全够用。但从性能上说,座椅一个是人造皮一个是真皮,0 到 100 公里加速一个要十几秒、一个只要几秒。车的"功能"都在,可开起来是天壤之别。做软件也一样:能不能吃是一回事,好不好吃又是另一回事。
这篇文章是性能测试概念篇。我们从"什么是性能测试"讲起,一路讲到性能测试的目的、常见性能指标(并发数、吞吐量、TPS/QPS、响应时间、资源利用率、错误率),再讲负载、压力、并发、稳定性这些测试类型的区别,最后落到性能瓶颈怎么定位、以及新手最容易踩的几个坑。你会理解一个核心思想:性能测试不是"把系统搞到死机"的恶作剧,而是用一套科学方法,回答"这系统到底扛不扛得住、快不快、稳不稳"。
什么是性能测试
先给个一句话定义:性能测试,是为了发现系统性能问题、或获取系统性能相关指标而进行的测试。它一般发生在真实环境或接近真实的环境里,在特定的负载条件下,通过工具模拟实际软件系统的运行及其操作,同时监控各项性能指标,最后对测试结果进行分析,从而确定系统的性能情况。
注意这句话里藏着的三个要素:场景是"特定负载"下(不是空跑,也不是随便点点),手段是"工具模拟"(用脚本模拟大量用户而不是人肉点击),产出是"指标 + 分析"(要数,更要针对这些数做判断)。这三点后面每一节都会反复用到。
那性能测试和功能测试到底有什么区别?我们用一个对照来看:
| 对比维度 | 功能测试 | 性能测试 |
|---|---|---|
| 回答的问题 | 功能对不对、符不符合需求 | 系统快不快、稳不稳、扛不扛得住 |
| 看重的对象 | 有没有 Bug、行为是否符合预期 | 指标好不好、资源够不够、有没有瓶颈 |
| 执行方式 | 一个一个用例验证 | 高并发、大负载下用工具批量压测 |
| 通过标准 | 输出与预期一致 | 指标达到预设的性能要求 |
| 关注维度 | 逻辑正确性 | 数量大、速度快、时间长、资源少 |
一句话:功能测试回答"能做吗",性能测试回答"做得好不好、能撑多久、多少人同时用还扛不扛得住"。
那站在软件的视角,什么才叫"性能问题"?举购物软件的例子:
- 购物过程中页面突然打不开,刷新之后又能打开;
- 双十一期间根本进不了商品页;
- 页面加载时间太长,顾客要等很久;
- 查询数据要很长时间才显示出列表;
- 网速明明很好,服务器却毫无响应。
这些问题的共同点是:功能看起来没错,但速度、稳定性、承载能力出了状况。它们往往平时不发作,一到抢购、秒杀、促销这种流量高峰才集中暴露——这正是性能问题最气人的地方:平时测不出来,上线就出事。
性能测试的目的
为什么要做性能测试?不是为了"完成个测试任务",而是有实实在在的业务价值。归纳起来主要是下面几件事:
- 获取性能指标:搞清楚系统在某个负载下的吞吐量、响应时间、并发能力、资源占用到底是多少,这些数是容量规划、采购硬件、报价评估的依据。
- 发现性能缺陷:找出只在高负载下才出现的毛病,比如内存泄漏、线程死锁、数据库连接池耗尽、缓存击穿等。这些缺陷在低并发下根本暴露不出来。
- 定位瓶颈:通过测试结果分析"卡在哪一环"——是前端渲染慢、网络带宽不足、后端 CPU 打满、还是数据库 SQL 太慢。瓶颈定位是性能调优的起点。
- 验证容量与稳定性:验证系统能否承受预期的业务量,以及长时间运行是否稳定(比如连续跑 3 天有没有内存越用越多、进程悄悄崩掉)。
- 作为性能调优和系统优化的依据:只有先测出"哪里不行、差多少",才能让开发有针对性的优化,优化完再复测,形成"测-调-再测"的闭环。
可以说,性能测试是把"系统能跑"这件事,从感性的"好像还行"变成理性的"具体能到多少"的关键一步。
常见性能测试指标
如何评估一个系统性能的好坏?不能靠感觉,要靠性能指标来统计和分析。性能指标是性能测试的语言,下面这些指标你能看懂、能说清含义,许多测试报告就难不倒你。先把全景摆出来,后面的几节再逐个掰开揉碎:
| 指标 | 一句话含义 | 衡量什么 | 常用单位/描述 |
|---|---|---|---|
| 并发数 | 同时访问/同时处理的能力 | 系统同一时刻能扛多少"同时" | 个(并发用户/并发线程) |
| 吞吐量 | 单位时间处理的事务/请求量 | 系统的处理能力与负载承受力 | TPS、QPS、KB/s |
| TPS | 每秒处理的事务数 | 业务事务级处理速度 | 事务/秒 |
| QPS | 每秒的查询(请求)率 | 接口/查询级处理速度 | 请求/秒、次/秒 |
| 响应时间 | 从发请求到收到响应的时间 | 系统快不快、用户体验 | 毫秒 ms、秒 s |
| 资源利用率 | CPU/内存/磁盘/网络的占用程度 | 资源是否打满、有没有瓶颈 | 百分比 % |
| 错误率 | 失败请求占全部请求的比例 | 系统在高负载下的可靠性 | 百分比 % |
看到没有,这些指标从不同侧面回答性能问题:并发数管"同时量",吞吐量管"处理量",响应时间管"快不快",资源复用管"累不累",错误率管"稳不稳"。一个完整的性能测试报告,通常要把这几类都覆盖到,因为单看任何一个都容易失真——比如并发极高但响应超慢,或者吞吐很高但错误率爆炸,都不能算"性能好"。
下面一节一个指标,逐一细讲。
并发数
并发数,通常指并发用户数。这个词在不同层面有不同的含义,很多人容易混淆:
- 从业务层面看,并发用户数指的是实际使用系统的用户总数。这里说的"并发"更接近"同时在用"的意思。
- 从后端服务器层面看,指的是 Web 服务器在一段时间内处理浏览器请求而建立的 HTTP 连接数,或由此生成的处理线程数。这是"真正同时落在服务器上的并发"。
课件里给了一个特别好的例子,我原样讲一遍并补上解读。一个已投入运行的 Web 系统,有 5000 名员工使用,最多同时有 2500 人在用。用户分别进行"浏览页面、填写订单、提交订单、查询订单"这些操作。那么这个系统的业务并发用户数是 2500——因为同一时刻最多 2500 人在线。而实际并发用户数(也就是真正同时向后端发起请求的)是"提交订单"和"查询订单"这两类操作的用户——因为浏览页面、填写订单这些操作,绝大多数时间是在本地等待,并不会真的向服务器发请求。
这里就引出一个特别关键的认知:"在线人数"和"并发数"不是一回事。2500 个人"同时在浏览页面",但真正同时敲击服务器、真正需要服务器同时处理的可能只有几十上百个。这是初学者最容易犯的错误——拿"同时在线人数"直接当"并发压测人数",结果压测了回去发现根本复现不了线上问题。
同时要注意,同一个"并发"在三层架构下还会有"放大"效应:一个浏览器请求进来,后端可能还要查询数据库、调用下游服务,导致数据库连接、线程池同时被占用。所以做并发测试时,还要考虑线程池大小、连接池上限这些"池子"到底装不装得下。
思考题 1:一个小型的公司内部考勤系统,公司有 300 名员工。早上 8:50 到 9:10 是打卡高峰,这个时段大概有 200 人同时在线打卡。请问这个系统的"业务并发用户数"和"实际并发用户数"分别应该填多少?为什么不能把"同时在线打卡的 200 人"直接当作压测时的并发数?
答案(详解):这里的"业务并发用户数"是 200——它就等于"同时在线的用户数",指的是同一时刻有多少人在使用系统。而"实际并发用户数"应该是真正同时向后端发出打卡请求的人数,通常远小于 200。原因是打卡这个动作在时间上非常分散:这 200 人虽然是同一时段在线,但每人点一下"打卡"只是一瞬,请求是错开的,真正在某一瞬间同时打到服务器的,可能只有几个人到几十个人。所以不能把"同时在线 200 人"直接当压测并发数,否则会严重高估服务器的并发压力,测出来的结果并不能代表真实情况。做一个合理的估算是这样:如果点一次打卡大约需要 2 秒、200 人在 20 分钟内(1200 秒)完成打卡,那么每秒约 200/1200 ≈ 0.17 个用户开始打卡,考虑每个打卡请求本身占用服务器的处理时间很短,实际任何一瞬间落在服务器上的并发连接数通常在个位数到十几位之间。可见"在线数"与"并发压测数"是两码事。
吞吐量:TPS 与 QPS
吞吐量,指的是单位时间内系统成功处理并完成响应的事务(或请求)数量,它直接体现软件系统的负载承受能力。一般经验是:吞吐量越高,系统能承受的并发越多,性能越好。这是后面所有指标里最常被当成"核心指标"的一个。
吞吐量从不同维度又分成两类:
- 按请求数量分:TPS 和 QPS;
- 按网络数据包分:用 KB/s(或 MB/s)表示单位时间传输的数据量。
TPS(Transactions Per Second),每秒处理的事务数,用来衡量系统在一定时间内能够处理的事务个数。它的计算公式是:
TPS = 总的成功事务数 / 总的运行时间
注意"成功"二字很关键——算的是成功处理的事务,失败的、超时的通常不计入(或用错误率另外统计)。课件给了两个计算例子:
例 1:某系统 1 分钟处理了 1000 个业务,那么 TPS = 1000 / 60 ≈ 16.7。这里的"业务"可以被认为是一个事务。
例 2:假设 2022 年最高的一天有 10 万笔交易,要预测 2023 年需要多少 TPS 才合格。先把每笔交易当成一个事务,理想平均下来的理论 TPS = 100000 / (24 × 60 × 60) ≈ 1.2。但实际业务往往集中在某些时段突然爆发,不会平均摊到每一秒,所以这个"理想值"并不够用,需要进一步修正:
- 如果没有更详细的数据,可以根据二八定律(大约 80% 的事务在 20% 的时间内完成)来估算 TPS: TPS = 100000 × 0.8 / (24 × 60 × 60 × 0.2) ≈ 4.6。这里的 0.8 是"8 成事务",分母里的 0.2 是"20% 的时间",意思是那 8 万笔交易挤在一天里 20% 的时间里完成。
- 如果有更详细的数据,比如知道 5 万笔交易集中在晚上 8 点到 9 点这一个小时完成,那么 TPS = 50000 / (60 × 60) ≈ 13.9。如果再考虑往年业务增长,假设每年增长 30%,则 TPS = 50000 × 1.3 / 3600 ≈ 18。
这个例子非常有用,它提醒我们:算 TPS 需求不是简单地把总量平均到 24 小时,而是要结合业务高峰、二八分布、增长预期来做估算。这也是容量规划最实用的一课。
QPS(Queries Per Second / Requests Per Second),每秒查询率,也就是每秒能处理的查询或请求数。它与 TPS 的关系需要厘清:如果一个事务里只有一个接口、而这个接口是查询接口,那么 QPS 就等于 TPS。更一般地说:
- 一个事务可能由一个或多个接口操作组成;
- 若一个事务 = 一次完整的业务操作(查询、提交、支付等都算),则 TPS 是"业务级"的量;
- QPS 更偏向"单个请求/查询"的量。
所以不能死记"QPS 一定等于 TPS",要看你拿它衡量的是"一个完整事务"还是"一个接口请求"。这也是后面"边界与坑"一节要强调的"别把指标张冠李戴"。
关于吞吐量还有一个重要的辨析案例,课件讲得非常清楚,我完整复述一遍:
有 A、B 两种场景。
- A 场景:100 个并发用户,每个用户每隔 1 秒发一个请求;
- B 场景:1000 个并发用户,每个用户每隔 10 秒发一个请求。
两个场景的吞吐量是相同的——都是每秒 100 个请求(A 是 100 人每人每秒 1 个,B 是 1000 人每人每 10 秒 1 个)。但是 A 场景的思考时间短(隔 1 秒就发下一个请求),所以 A 场景占用的系统资源更多。这里想表达的是:在吞吐量相等的情况下,谁更"紧凑"地压着系统,谁的资源开销就更大。这也说明,设计压测场景时,"并发数 + 思考时间 + 吞吐量"三个量要一起看,单独拿出来都可能产生误导。
顺带一提,吞吐量不是说越高越好就无脑追求。过高的吞吐压低响应时间、挤爆资源,往往意味着系统在"透支",后面的"性能拐点"一节会专门讲这个平衡。
响应时间
响应时间,指的是应用系统从请求发出的那一刻开始,到客户端接收到最后一个字节数据为止所消耗的时间。它验证的是"系统处理速度快不快",直接决定用户体验。
对 Web 系统而言,这个总响应时间其实由两大部分组成:
- 前端展现时间:主要指页面渲染、脚本执行、图片加载等浏览器端花的时间;
- 系统响应时间:包含服务器处理、数据库查询、通讯网络传输等后端花的时间。
换句话说,用户在浏览器里感受到的"整体等待",往往是"后端返回数据的时间 + 前端渲染的时间 + 中间网络传输的时间"三者之和。做性能测试时,搞清楚慢在哪个环节很重要——很多人只盯着后端接口的耗时,忽略了前端渲染占了半壁江山,结果后端拼命优化,用户体验却几乎没变。
关于响应时间,有两点业内经验值得知道(它们属于"经验法则",具体阈值因业务而异,不是放之四海皆准的标准,但很常用):
- 响应时间的 2-5-10 原则:一般认为 2 秒内用户感受良好,2~5 秒基本可接受,超过 5 秒用户开始明显不耐烦,接近或超过 10 秒就容易流失。这是偏通用的经验划分。
- 别只看平均响应时间,要看百分位。平均响应时间很容易被"偶发高耗时"拉歪(比如 99% 的请求只要 100ms,但有个别请求要 5 秒,平均就被拉高了)。实践中更常用 P90 / P95 / P99(90%、95%、99% 的请求落在多少毫秒以内)来评估。一句话记住:平均数是表象,P99 才见真章。
顺带解释一下"事务响应时间"和"接口响应时间"的差别:事务响应时间是完成一整个业务操作(可能调好几个接口)的时间;接口响应时间是单个接口的时间。报告里要写清楚说的是哪个,否则又是"张冠李戴"。
思考题 2:一次压测中,系统共处理了 10 万个请求,平均响应时间为 90 毫秒,看起来又快又漂亮。但仔细看吞吐量的时间分布发现:平时大多数请求只要 40 毫秒,可每秒有一小撮请求要 3000 毫秒。请问"平均 90 毫秒"这个数字为什么有误导性?更该看哪些指标?
答案(详解):因为平均响应时间会被少数高耗时的请求严重拉偏。在这个例子里,绝大多数请求只有 40 毫秒,只要大约 1.6% 的请求耗时 3000 毫秒,就足以把平均值从 40 毫秒抬到 90 毫秒(40 × 0.984 + 3000 × 0.016 ≈ 87.4,约等于 90)。如果只报"平均 90 毫秒",管理者会以为系统整体挺快,却掩盖了"确实有小比例用户要等 3 秒"这个糟糕体验。更该看的是百分位指标:P90、P95、P99——它们分别表示 90%、95%、99% 的请求落在多少毫秒以内。比如报"平均 90ms、P99 为 3000ms",就同时传达了"绝大多数请求很快,但极少数慢请求仍要改进"这条更真实的信息。另外还要配合看错误率,确认慢是不是还伴随着超时失败。一句话:读性能报告时,别只看平均,要把平均数、分位数、错误率放在一起读。
资源利用率与错误率
资源利用率,通过查看系统各项资源的占用情况,来分析资源瓶颈。它主要关注服务器层面的几类资源:
- CPU:使用率是否长期打满。CPU 一直是高的,通常说明计算密集,或出现了死循环、GC 频繁等问题;
- 内存:是否存在持续上涨、回收不掉,进而导致内存泄漏或频繁的除旧换新(在老一代叫法里是"频繁 GC"/页面换出)风险;
- 磁盘:磁盘 I/O 是否成为瓶颈,尤其是日志写得多、数据库落盘重的系统;
- 网络:网络带宽、连接数、连接池是否吃紧。
判断资源瓶颈有一个朴素思路:哪项资源最先到接近 100%,它就大概率是当前的瓶颈所在。比如 CPU 95% 而内存只用了 30%,那先往 CPU 方向查;反之如果内存几乎打满而 CPU 很闲,那很可能是内存或链接/缓存方面的问题。因为是"谁先满谁瓶颈"的大致判断,具体还要结合业务场景。
错误率,指的是失败请求占全部请求的比例。计算公式很简单:
错误率 = 失败请求数 / 总请求数 × 100%
它衡量系统在高负载下的可靠性和稳定性。欠负载下一切正常,不代表高负载下不报错——比如连接池耗尽导致大量超时、数据库锁等待导致部分写失败、缓存雪崩导致回源把上游打爆等,都会让错误率在高并发时明显抬头。所以性能测试里错误率是必须盯的指标,一般要求错误率接近 0 或满足业务给定的容忍阈值。
并发用户、吞吐量与响应时间的关系
前面几个指标是分开讲的,但它们之间其实存在一条内在的联动曲线。把它理解了,你就把握住性能测试最核心的模型了。课件用"区间"的方式描述得很清楚:
- 空闲区间:并发用户数较少时,系统吞吐量低、响应时间短,系统处于"游刃有余"的空闲状态。
- 线性增长区间:随着并发用户数增加,系统吞吐量开始(近似)线性增长,系统性能进入"线性增长区间"。这个区间内,加多少并发,处理能力跟着涨,响应时间基本稳定。
- 过饱和区间:但增长不是无限的。吞吐量在某个点会达到饱和,这个点就叫拐点(饱和点)。在拐点之后,新来的请求不再被立即处理,请求开始排队,响应时间随之变长,吞吐量反而逐渐降低,系统进入"过饱和区间"。
性能拐点,通俗说就是系统从"快速响应"转折为"响应开始恶化"的那一个负载临界点。它是性能测试最主要的产出目标之一——找到它,你就知道系统"健康的边界"在哪,超过这个边界性能就会崩。
这里有个重要的直觉要建立:并发、吞吐、响应时间不是三个独立的量,而是同一条曲线上的一体三面。看下面这个简化对照能帮你串起来:
| 区间 | 并发用户数 | 吞吐量 | 响应时间 |
|---|---|---|---|
| 空闲区间 | 少 | 低 | 短(快) |
| 线性增长区间 | 增加 | 近似线性增长 | 基本稳定 |
| 拐点附近 | 临界值 | 到达饱和点 | 开始变长 |
| 过饱和区间 | 过多 | 反而降低 | 明显变长(排队) |
记这条曲线的方式是把"拐点"当成分水岭:拐点之前是"加人有效"的良性区,拐点之后是"加人反噬"的恶化区。性能测试的一项核心工作,就是用逐步加压的方式,把这条曲线上最关键的那个"拐点"找准。
性能测试关注点:不同角色的视角
同一个性能测试,不同角色关心的事完全不同。这一点太容易被忽视,但理解它,你才知道自己的性能报告该写给谁看。从客户端发一个请求到收到响应的整体链路里,任何一环都可能慢,而不同角色只关注和自己关系最大的那一段。
主要有四种角色:
-
终端用户:对于终端用户来说,性能表现为用户进行业务操作时的主观响应时间。用户最关心从提交请求到收到响应要多长时间——也就是我们前面说的"响应时间",它包含了系统响应时间和前端展现时间的整体体感。用户不关心你的 GC 调不调、索引建没建,只关心"快不快"。
-
系统运维人员:运维除了关注单个请求的响应时间,更关注大量用户并发访问时对系统整体健康的影响,以及更大负载下系统的运转状态。他们的关注点偏"全局":
- 追求全局利益最大化,往往要在"最大并发用户数"和"响应时间"之间做权衡取舍;
- 关心系统并发处理能力、容量、数据库调优,以及长时间运行的稳定性和可扩展性。
课件给了一个很能说明问题的取舍例子。当下面两个方案摆在一起时:
- A 方案:100 万并发访问用户,登录响应时间 3 秒;
- B 方案:500 万并发访问用户,登录响应时间 8 秒。
这种情况下,运维往往更倾向第二种——因为对大量用户同时涌入的产品来说,能"兜住更多人"往往比"单次更快半秒"更重要。这就是典型的"响应快 vs 容量大"的权衡,没有绝对的对错,只有处于哪个角色、看重哪个目标。
-
软件设计开发人员:关注算法设计、架构设计、性能最佳实践、数据库相关、软件性能的可测试性等方面。比如算法要高效、不能有内存泄漏;架构要能支撑容量的扩展。他们负责的是"根子上要快"。
-
性能测试人员:工作重点在性能测试场景的设计、脚本的开发和执行,以及性能缺陷的排查与定位。测试人员除了要有极宽的知识面——如系统架构、存储架构、网络架构等全局知识——还要有大量知识积累,比如数据库 SQL 语句执行计划优化、JVM 内存回收、多线程常见问题等。
这里想特别强调一句:可见性能测试的范围太大了,不同角色对性能有不同的处理方式。正因如此,做性能测试前一定要先确认"这份报告要服务谁、要回答什么决策"。给运维看,重点是容量与拐点;给开发看,重点是瓶颈定位与优化建议;给产品/领导看,重点是能否支撑预期业务量。
性能测试的分类
把性能测试按照目的和手法细分,可以得到几种典型类型。它们经常被混淆,但其实各有侧重。课件把这几类讲得很系统,我逐一展开:
基准测试(Benchmark Testing),又称单用户测试。主要用来监测被测系统在较低压力下的运行状况并记录相关数据。当性能测试环境确定以后,通常选取业务模型中的重要业务做基准测试,对被测系统施加一定压力,从而获取系统在单用户运行情况下的各项性能指标,为后面的多用户并发测试和混合场景测试提供参考依据。
理解基准测试最朴素的方式:它是"地基数据"。先测出一个用户跑起来的耗时、资源占用,后面加并发时才能对比——"从 1 个用户变 100 个用户,响应时间涨了多少?",这个"涨了多少"需要基准来做参照。所以基准测试往往是整个性能测试流程的第一步。
并发测试(Concurrency Testing),用于评估被测系统某些特定操作同时发生时的性能表现。比如系统被多个用户同时登录时的响应能力,或某一功能被多个用户同时操作时的表现。通过并发测试,不仅能拿到多用户并发时的性能指标,还能发现并发条件下才可能出现的问题——内存泄漏、线程锁、资源争用问题。例如模拟多个用户同时访问某一条数据,或模拟多个用户同时更新数据,可能暴露出数据库访问错误、写入错误等。几乎所有性能测试都会涉及一些并发测试,但并发测试对"并发时间"要求比较苛刻,通常要借助专门的性能测试工具,用多线程或多进程来模拟多个虚拟用户的并发操作。
一句话总结并发测试的定位:它专门盯"同时抢着做同一件事"会不会出乱子。抢同一行更新、抢同一个库存、抢同一个连接——这类问题只在"同时"发生时冒头。
负载测试(Load Testing),是性能测试的一种类型,用于评估被测系统在预期的不同负载下的行为。负载测试关注系统处理不同负载的能力,这些负载可通过控制并发用户或进程的数量来实现。进行负载测试时,通过对系统不断增加并发访问负载、监测系统性能变化,直到系统的某项或多项性能指标达到安全临界值,最终确定在满足该安全临界值条件下系统所能承受的最大负载量。简而言之,负载测试就是通过逐步加载的方式来确定系统的处理能力。
负载测试有个特别贴切的比喻——举重运动:通过不断给运动员加重量,来确定他在身体状况保持正常的前提下能举起的最大重量。通过负载测试可以获取系统能够达到的峰值指标。
课件给的例子:一个系统的响应时间要求不超过 2 秒。在这个前提下不断增加用户访问量,响应时间会变长,当访问量超过 1 万人时响应时间超过了 2 秒,那么就能确定:在"响应时间不超过 2 秒"的前提下,系统的最大负载是 1 万人。负载测试常用于系统的性能验证、性能诊断和性能调优等场景。
压力测试(Stress Testing),用于评估被测系统在高于预期、高于指定容量的负载,或低于最少需求资源条件下(比如计算能力、带宽、内存不足时)的行为。压力测试关注系统处理超出预期或特定峰值负载的能力。进行压力测试时通常采用逐步增加负载的方式,使系统某些资源达到饱和甚至失效,从而发现那些只有在高负载下才会出现的缺陷——如同步问题、内存泄漏等。通过压力测试,也能找出系统的性能拐点,获得系统所能提供的最大服务级别(能承受的最大压力),评估系统在峰值负载或超出最大负载情况下的处理能力。压力测试主要用于性能诊断、性能调优和容量规划等场景。
把上面四类放一张表对着一看,差别就出来了:
| 类型 | 加压方式 | 目标 | 结果关注 | 典型应用 |
|---|---|---|---|---|
| 基准测试 | 单用户、低压力 | 建立参照基线 | 单用户下的各指标 | 性能测试的第一步/参照 |
| 并发测试 | 模拟大量用户"同时"做同操作 | 找并发冲突类问题 | 锁、内存、资源争用 | 排查并发缺陷 |
| 负载测试 | 逐步加负载到指标临界 | 找"满足指标前提下"的最大负载 | 健康状态下的峰值指标 | 性能验证、诊断、调优 |
| 压力测试 | 持续加压突破极限 | 找系统崩溃点、最大承受力 | 饱和、失效、崩溃点 | 容量规划、极限评估 |
负载测试与压力测试的区别
“负载测试”和“压力测试”是四类里最容易被搞混的一对,专门拿出来掰清楚。
关键区别一句话:负载测试是在"保持性能指标要求、要求还满足"的前提下,测系统能承受的最大负载;压力测试则是把系统往"性能已经失守、逼近极限"的方向加压,看它什么时候崩。
还拿课件的例子:系统要求响应时间不超过 2 秒。
- 做负载测试时发现:访问量到 1 万时,响应时间不超过 2 秒;访问量超过 1 万,响应时间就超过 2 秒。那么在满足指标的前提下,系统能承受的最大访问量就是 1 万——这是负载测试的结论。
- 做压力测试时,则继续往上加:访问量加到 2 万,响应时间被拉到 5 秒;加到 3 万,系统直接崩溃、无法响应。由此确定系统能承受的极限访问量是 3 万——这是压力测试的结论。
| 对比维度 | 负载测试 | 压力测试 |
|---|---|---|
| 加压目标 | 找到"指标达标"内的最大负载 | 找到"不达标/崩溃"的极限 |
| 是否突破性能指标 | 不突破,停在"还合格"的临界 | 主动突破,直到饱和甚至失效 |
| 关注的问题 | 健康状态下的承载上限 | 极限状态下的行为与崩溃点 |
| 与拐点的关系 | 落在拐点附近(刚好合格) | 越过拐点继续加压 |
| 典型场景 | 验证、调优、容量测算 | 容量规划、极限评估、找崩溃缺陷 |
同样一句"最大能承受多少",负载测试给出的是"爽快地能扛多少",压力测试给出的是"硬抗最多是多少、多了会怎样"。两种都是合法且有用的测试手法,区别只在于你想回答"健康上限"还是"极限上限"。
思考题 3:一个订单系统的性能要求是"响应时间不超过 2 秒,错误率不超过 1%"。你做了两轮测试:第一轮把并发从 100 逐步加到 5000,发现并发到 5000 时响应时间正好 2 秒、错误率 0.8%,都还达标;第二轮从 5000 继续往上加,并发到 8000 时响应时间飙到 6 秒、错误率 15%,并发到 12000 时系统彻底无响应。请问这两轮测试分别属于什么类型的测试?系统的"最大安全负载"和"极限承受力"分别是多少?
答案(详解):第一轮是负载测试——它一直加负载,但把目标停在"指标还能满足"的临界点,最终找到的是在达标前提下的最大负载,也就是并发 5000(再往上就不满足了)。第二轮是压力测试——它在负载测试的基础上继续突破,主动越过合格线,去观察性能恶化和崩溃的边界。所以:系统的"最大安全负载"是并发 5000(此时响应时间 2 秒、错误率 0.8%,刚好达标);而"极限承受力"要看你怎么定义"极限"——如果以"还能响应不崩溃"为界,并发 8000(虽然性能已严重恶化但仍能返回结果)算是一个勉强能扛的量级,并发 12000 系统完全无响应,已经是彻底崩溃的极限。这个例子正好对应课件的对照:负载测试回答"健康状态下最多扛多少",压力测试回答"压到哪会崩、怎么崩"。
稳定性测试
稳定性测试,是在负载测试的基础上,执行较长时间的测试来检查系统的稳定性。课件指的"较长时间"通常是 3 × 24 小时以上。
为什么要跑这么久?因为很多问题不是几分钟能暴露的:
- 内存泄漏:内存随运行时间缓慢上涨,跑几小时不明显,跑几十小时可能把内存耗光;
- 连接/句柄泄漏:连接池、线程、文件句柄只借不还,长时间跑完就耗尽;
- 缓慢的性能退化:比如缓存逐渐失效、GC 日渐频繁,导致响应时间一天比一天慢;
- 资源枯竭与进程悄悄崩溃:深夜某个时刻资源耗尽,服务自动被重启或宕机。
所以稳定性测试的基本动作是:在接近生产/预期负载的持续压力下,长时间观察吞吐、响应时间、资源占用、错误率是否平稳。如果这些指标在 3 天里始终稳定在一个正常区间,系统才算"稳得住";如果发现响应时间逐日走高、内存只涨不降,那大概率就有泄漏类问题在累计。
一句话记:负载测试问"扛不扛得住高峰",稳定性测试问"扛不扛得住持久"。
性能瓶颈的定位思路
拿到了指标、发现了"性能不好",接下来就是性能测试里最有技术含量的部分——定位瓶颈到底在哪。前面说过,从客户端发请求到收到响应,整条链路里任何一环都可能慢,所以定位的关键是"分层排查、逐段排除"。下面是一条实用的思路:
-
先看整体有没有"明显断崖":用并发–吞吐/响应时间曲线,找出拐点位置,确定"大概在哪个负载量级开始恶化",缩小排查范围。
-
按链路分段:把一次请求拆成"前端渲染 → 网络传输 → 网关/反向代理 → 应用服务器(中间件)→ 数据库/下游服务",用监控数据+日志定位耗时花在哪一段。前端慢看渲染、网络慢看带宽/链路、应用慢看代码和服务端资源、数据库慢看 SQL 与索引。
-
盯服务器资源利用率:CPU、内存、磁盘 I/O、网络四类资源里,谁先接近 100%,谁就是当前最可疑的瓶颈方向。比如 CPU 打满、其他都很闲,多半是计算逻辑、死循环或者 GC 频繁;内存打满,查泄漏和驻留对象;磁盘 I/O 打满,查日志写入和数据库刷盘。
-
审查慢接口/SQL:用性能分析工具(如数据库执行计划分析)找出最耗时的 SQL,检查是否命中索引、是否存在大表全扫、是否存在 N+1 查询;代码层面看有没有大对象导致频繁内存回收、有没有锁竞争。
-
做减压定位实验:把怀疑的环节拿掉或降级试跑,看问题是否消失。比如关掉某段缓存,看压力是否暴增,以此反推缓存的作用;限制并发,看是连接池不够还是计算不够。
-
记录与复测:每一次定位和优化后都要复测同场景,用数据确认"瓶颈是否真被解决、有没有把瓶颈转移到别处"。
需要强调,定位瓶颈本质是一个"不断缩小区间"的排除过程,最忌讳的是"一把梭"乱猜。有了指标打底、分层分段、逐项排除,才能既快又准地把真正的瓶颈揪出来。
边界与坑
这一节是很多测试老手踩出来的坑,也是理解前面所有概念后最该补的一课。这里集中讲三个最典型的"坑"。
坑一:指标一定要结合业务看,脱离业务谈指标是空谈
"并发 1000、TPS 500、响应 200ms"看起来很美,但如果业务要求的日活只有几百、交易量只有几千,那这套漂亮的数字毫无意义;反过来,一个面向几亿用户的产品,响应 2 秒可能都嫌太慢。所以:
- 先有性能需求(Performance Requirement),后做性能测试。所谓性能需求,就是业务给出的、可以量化的指标,比如"并发用户数不少于 1 万""下单成功响应不超过 3 秒""TPS 不低于 500""错误率不超过 1%""系统支持 7×24 小时稳定运行"。测试的目标就是去验证系统是否满足这些要求。
- 指标之间要一起解读,不能单独报喜。吞吐高但错误率高、并发高但响应成倍变慢,都不能得出"性能好"的结论。
- 同样的指标,对不同业务含义不同。金融交易系统容忍不了任何一次丢失,视频网站更在乎吞吐和首屏,所以在"指标好不好"这件事上,答案永远藏在业务场景里。
坑二:虚拟用户数(Vuser)不等于 TPS
这是性能测试领域最经典的混淆。虚拟用户(Virtual User,Vuser) 是工具模拟出来的"一个用户",而 TPS 是系统实际处理的事务速率。两者之间的关系是:
TPS ≈ 并发用户数 × 每个用户单位时间发起的事务数
举个例子:你压进了 1000 个虚拟用户,但如果每个用户隔 10 秒才发一个请求,那么总 TPS 也就只有 1000/10 = 100;而如果你只压 100 个用户但每人每秒发 1 个请求,TPS 依然是 100。前面"吞吐量"一节里那个 A/B 场景,本质就是在这个公式上做文章。
所以在写报告、谈指标时,一定要分清你报的"1000"到底是"1000 个虚拟用户"还是"TPS 1000",二者完全不是一回事。这也是为什么场景里要设计好思考时间(think time)——不设思考时间会让所有用户疯狂连发,测出来的 TPS 和资源占用都失真,不能代表真实用户行为。
坑三:线性扩展是假象,别被"加机器就翻倍"骗了
很多人在做容量规划时想当然:一台机器能扛 1000 并发,那加一台不就能扛 2000 了?这叫线性扩展的假象。现实中几乎没法做到理想线性扩展,原因很多:
- 共享的瓶颈不随机器增长而线性增长:数据库、网关、消息中间件、缓存分发这些"公共资源"往往是单点或多机共享的,加应用实例后它们反而成为新的瓶颈;
- 加机器带来的"同步与协调"开销:服务变多后,注册发现、负载均衡、分布式锁、事务一致性协调本身也在消耗资源和增加延迟;
- 数据层不是简单加机就行:数据库主从、分库分表、缓存集群都有各自的天花板。
所以要做容量扩展的正确姿势是:利用压力测试测出"加一台确实能提升多少"的真实曲线,找到扩展的瓶颈点,几号机几个点地做扩容验证,而不是拍脑袋按比例线性放大。
这三条坑,核心其实都可以归纳成一句话:指标、单位、模型都要回到真实业务上去校验,凡是"看着唬人但经不起推敲"的数字,都要先把口径问清楚。
当然,边界与坑远不止这三个,比如"测试环境与生产环境差异导致的数字失真""冷启动 vs 预热后的性能差异""多语言多客户端造成的指标口径不一致"等。但把这"三座山"先翻过去,你再看性能测试报告,就不会那么容易糊里糊涂地信了。
自测题(综合):请判断以下说法是否正确,并说明理由。
- "我们系统 TPS 是 2000,说明系统每秒能同时处理 2000 个并发的虚拟用户。"
- "压力测试结果发现系统 10000 并发时崩溃,所以这个系统最多只能支持 10000 个用户使用。"
- "CPU 使用率越高,说明系统性能越差。"
- "一个接口的 P95 响应时间比平均响应时间更重要。"
答案(详解):
- 错误。TPS 是每秒处理的事务数,虚拟用户(Vuser)是工具模拟的"一个用户"。一个用户可能每秒发多个请求,也可能很久才发一个(取决于思考时间)。"TPS 2000"只能说明每秒完成了 2000 个事务,不能直接推出"同时有 2000 个虚拟用户"。二者要通过"用户数 × 每人每秒事务数"换算,不可混为一谈(详见"坑二")。
- 错误。压力测试测出的是"系统在什么负载下性能崩溃"的极限承受力,是技术边界,不代表业务上就该按这个数去规划使用量。真实项目里会留安全余量,通常以"满足性能需求(响应时间、错误率达标)的最大安全负载"为使用依据,而不是用到崩溃点。10000 并发崩溃,恰好说明 10000 已经远远超过安全边界,反倒应该把使用上限设得低很多(比如硬件、架构允许时,或许以几千为规划目标)。(详见"负载测试与压力测试的区别"。)
- 错误(不完整)。单纯看"CPU 使用率高"不能下"性能差"的结论——CPU 高只说明 CPU 这个资源被充分利用,可能是系统在高效地干活,也可能是某个环节在低效地空转。性能好坏要看"在资源占用合理的情况下,吞吐量和响应时间是否达标"。只有当 CPU 接近 100% 且吞吐不再上涨、响应开始变差、或存在明显浪费(死循环、频繁内存回收)时,CPU 才算"性能瓶颈"。所以更准确的说法是:CPU 高本身不是坏事,"CPU 打满压着吞吐/响应变差"才是问题。
- 通常正确。平均响应时间容易被少数超长请求拉偏,P95(以及 P99)能更真实地反映"绝大多数用户实际体验",因此在评估用户体验时,百分位指标通常比平均数更有参考价值。但它不是"取代"平均数,而是与平均数、错误率等一起解读才完整——严格说"比其他指标更重要"这句话也不够严谨,最稳妥的说法是"P95 比平均响应时间更能反映真实体感"。(详见"响应时间"一节。)
到此,我们走完了性能测试的概念篇。你知道了性能测试回答的是"能做之外,做得好不好",理解了它从"获取指标、发现缺陷、定位瓶颈、验证容量、支撑调优"这几个角度产生价值;认识了并发数、吞吐量(TPS/QPS)、响应时间、资源利用率、错误率这几大指标各自的含义,也看清了并发、吞吐、响应时间在同一条拐点曲线上一体三面、彼此联动;区分了用户、运维、开发、测试四个角色看待性能的不同侧重;最后把基准、并发、负载、压力、稳定性这几类测试掰开揉碎并单独厘清了"负载 vs 压力"这对最容易混淆的概念,还顺着"分层分段排查"的思路讲了瓶颈定位,提醒你别踩"指标脱离业务、Vuser 当 TPS、迷信线性扩展"的三个坑。
如果你是自己给自己项目做性能测试,接下来会需要一套趁手的工具。概念篇里我们大量提到"用工具模拟虚拟用户、逐步加压、采集指标",下一篇我们进入实战篇,讲一讲怎么挑工具、怎么设计一个能用思考时间和并发梯度逐步加压的场景,以及拿到一坨 TPS、P95、CPU 数据之后,怎么一步步把它们翻译成"系统到底行不行"的结论。
准备好了吗?先把这篇文章里的几个概念理顺——尤其是那个"拐点",它是整场性能测试最重要的一道分水岭。
还没有评论 — 第一条由你来留。