如果你开发过应用程序,一定担心过这样的场景:代码在本地跑得好好的,一上线就卡得不行,用户投诉电话接到手软。性能测试就是用来避免这种尴尬局面的。
本文用最直白的语言,告诉你性能测试是什么、为什么要做、怎么做。看完这篇文章,你就能理解性能测试的基本套路,知道从哪里开始动手。
为什么要做性能测试
想象一个场景:你做了个电商网站,平时访问的人不多,运行得挺流畅。突然有一天搞促销活动,几千人同时涌进来抢购,结果网站直接崩了,一单都没成交。
更糟糕的是,你不知道问题出在哪里。是服务器内存不够?还是数据库扛不住?还是代码写得有问题?为了保险起见,你只能加服务器、加带宽,成本蹭蹭往上涨,但效果可能并不明显。
性能测试就是用来解决这个问题的。它能在真实用户来之前,提前发现系统能承受多大压力,瓶颈在哪里,该怎么优化。
第一步:想清楚要测什么
性能测试不是上来就疯狂发请求,而是要先搞清楚目标。你到底想知道什么?
常见的测试目标
找到系统的承受极限:我的系统最多能同时处理多少用户?超过这个数会怎样?
发现内存泄漏:系统跑着跑着为什么越来越慢?内存是不是有问题?
建立性能基准:正常情况下响应时间应该是多少?超过多少就算有问题?
验证扩容策略:加了机器之后性能真的提升了吗?提升了多少?
从哪个目标开始
如果你是第一次做性能测试,建议从找到承受极限开始。这个目标最直观,也最实用。知道了系统的极限,你就能估算需要多少服务器资源,该在什么时候扩容。
第二步:选对测试类型
性能测试不是一种,而是好几种,每种解决不同的问题。
负载测试:模拟真实使用场景
就像餐馆在开业前先让员工模拟用餐流程,看看能不能应付得过来。负载测试模拟的是正常情况下的用户数量,看系统表现如何。
举例:你的电商网站平时有 500 人在线,负载测试就模拟 500 人同时购物的场景,看响应时间、成功率等指标是否正常。
压力测试:找到崩溃点
继续用餐馆打比方,压力测试就是看这个餐馆最多能同时接待多少客人。超过这个数,就会乱套——服务员忙不过来,后厨出餐太慢,客人等得不耐烦开始投诉。
举例:你不断增加并发用户数,从 500 到 1000 到 2000,看看系统在哪个点开始出问题——响应变慢、报错增多、甚至直接崩溃。
耐久性测试:发现慢性病
有些问题不是一上来就暴露的,而是随着时间慢慢显现。就像水管漏水,一开始只是滴几滴,时间长了就成水灾了。
举例:让系统在中等负载下连续跑 24 小时,看内存是不是一直在涨(内存泄漏),看响应时间是不是越来越慢(性能退化)。
尖峰测试:应对突发流量
模拟突然涌入大量用户的场景,比如明星突然发了条微博带了你的链接,瞬间几万人涌进来。
举例:系统原本 500 人在线,突然 5 秒内涌入 5000 人,看系统能不能扛住,多久能恢复正常。
容量测试:数据库压力测试
测试数据库在数据量很大的情况下是否还能正常工作。
举例:数据库里有 10 万条用户数据时查询很快,如果有 1000 万条呢?还能在 1 秒内返回结果吗?
小白建议
第一次做性能测试,从负载测试和压力测试开始。这两个最基础,也最实用。知道了系统的正常表现和极限,其他问题就容易发现了。
第三步:隔离测试环境
这一步很重要但经常被忽略。
假设你的系统调用了第三方支付接口,性能测试时如果真的去调用支付接口,会有两个问题:一是可能产生真实费用,二是支付接口如果慢,你分不清是自己系统慢还是支付接口慢。
解决办法是用桩代码(Stub)
桩代码就是假的接口,模拟真实接口的行为,但跑在本地。这样就能把外部依赖隔离开,只测试自己的代码。
Wiremock 是一个很好用的工具,可以快速搭建假接口。比如你的系统要调用支付接口,Wiremock 可以模拟一个假的支付接口,返回"支付成功"的响应,但实际不会真的扣钱。
模拟慢速接口
有时候你还需要模拟外部接口很慢的情况。比如支付接口平均响应时间是 2 秒,你需要测试在这种情况下你的系统会不会被拖累。
这时候可以用 Pumba(Docker 环境)或 Chaos Mesh(Kubernetes 环境)等工具,给网络添加延迟。
第四步:选择合适的工具
工具分两类:一类用来生成压力,一类用来监控系统。
压力生成工具
就像健身房的测力器,给系统施加压力。
JMeter:图形界面,点点鼠标就能配置测试,适合新手。功能强大,支持各种协议(HTTP、数据库、消息队列等)。缺点是界面有点老旧,配置复杂场景需要点时间。
Gatling:代码方式编写测试脚本,适合程序员。性能比 JMeter 好,报告也更漂亮。缺点是需要会写代码。
K6:和 Gatling 类似,用 JavaScript 写脚本,上手门槛低。
Apache Bench (ab):命令行工具,适合快速简单的测试。比如测试单个接口能不能扛住 1000 并发。
小白建议:如果你会写代码,优先选 Gatling 或 K6;如果不太会写代码,选 JMeter。
监控工具
压力测试运行时,你需要知道系统内部发生了什么。CPU 用了多少?内存涨了没?数据库连接池满了吗?
Prometheus + Grafana:这是最常用的组合。Prometheus 收集数据,Grafana 画图表。Grafana 有很多现成的仪表盘模板,拿来就能用。
Jaeger:如果你想看请求在系统里的完整流程(从接口进来,到调用数据库,到返回结果),Jaeger 可以帮你追踪整个链路。
小白建议:如果系统已经有 Prometheus,直接用 Grafana 画图就行。如果没有,可以先用 JMeter 自带的报告,等熟练了再研究监控系统。
第五步:看懂关键指标
测试跑起来后,会产生一堆数字。哪些是重要的?
响应时间
用户从发起请求到收到响应需要多久。这是用户最直观的感受。
举例:平均响应时间 100ms,但 P95 是 5 秒,说明虽然大部分请求很快,但有 5% 的用户要等 5 秒,体验很差。
吞吐量(RPS)
系统每秒能处理多少请求(Requests Per Second)。这个指标反映系统的处理能力。
举例:系统 RPS 是 1000,说明每秒能处理 1000 个请求。如果你预计有 500 并发用户,每个用户平均每秒发 3 个请求,那需要 1500 RPS,当前系统就不够用。
错误率
请求失败的比例。正常情况下应该接近 0%。如果错误率开始升高,说明系统快扛不住了。
系统资源
小白建议:重点关注 P95 响应时间、错误率和 CPU 使用率。这三个指标最能反映系统的真实状态。
第六步:学会保护系统
当系统遇到超高负载时,如何保证不会彻底崩溃?这里有几个常用的保护机制。
超时设置
给每个外部调用设置超时时间。比如调用支付接口,如果 3 秒还没返回,就主动放弃,返回错误信息给用户。这样可以避免线程被无限期占用。
就像排队等餐,如果等了 30 分钟还没上菜,你会选择退款走人,而不是一直等下去。
断路器
如果某个外部服务连续失败多次,就暂时停止调用它,直接返回错误。等一段时间后再尝试调用,如果恢复了就继续用。
就像家里的电闸,短路了会自动跳闸,避免烧坏电器。
限流
限制系统在单位时间内接受的请求数量。超过限制的请求会被拒绝,返回"系统繁忙,请稍后重试"。
就像景区限流,每天只能进 1 万人,超过了就不让进了,避免景区承载不了。
小白建议:第一次做性能测试,重点先搞清楚系统的极限在哪里。保护机制可以后面再慢慢加。
第七步:记录测试结果
做性能测试不是跑完就算了,要把结果记录下来,方便对比和分析。
建议的记录方式
测试序号 | 并发用户数 | 持续时间 | 总请求数 | 成功率 | P95响应时间 | CPU使用率 | 内存使用率 | 备注 |
|---|---|---|---|---|---|---|---|---|
1 | 100 | 5分钟 | 30000 | 100% | 50ms | 40% | 60% | 正常 |
2 | 500 | 5分钟 | 150000 | 100% | 120ms | 70% | 65% | 正常 |
3 | 1000 | 5分钟 | 300000 | 99.8% | 500ms | 85% | 70% | 开始变慢 |
4 | 1500 | 5分钟 | 450000 | 95% | 2000ms | 95% | 75% | 出现大量超时 |
5 | 2000 | 5分钟 | 600000 | 60% | 5000ms | 98% | 80% | 系统接近崩溃 |
从这个表格可以看出:
结论:系统的安全并发数是 500,极限是 1500。建议日常运行不要超过 800 并发,留出缓冲空间。
从哪里开始
如果你是第一次做性能测试,建议按这个顺序来:
第一周:搭环境
在测试环境部署你的应用,安装 JMeter,熟悉基本操作。不用着急测试,先把工具玩明白。
第二周:跑第一个测试
选一个最简单的接口(比如查询用户信息),用 JMeter 模拟 10 个并发用户,持续 1 分钟。看看能不能跑通,响应时间多少,有没有报错。
第三周:逐步加压
把并发数从 10 增加到 50、100、200,看看系统在什么时候开始变慢,在什么时候开始报错。记录下每次测试的关键指标。
第四周:分析瓶颈
根据测试结果,找出系统的瓶颈是 CPU、内存还是数据库。针对瓶颈进行优化,然后再测一遍,看看效果。
不要追求完美
性能测试是个循序渐进的过程,不要指望一次就搞定所有问题。先从最简单的开始,逐步深入。每次测试都能发现一些问题,每次优化都能提升一点性能,积累多了,你自然就成了性能测试的老手。