简介:这份PDF资料聚焦Web性能测试的基础概念与实施流程,面向刚接触性能测试的初级测试人员与开发人员,帮助其建立从理论到落地的完整认知。内容围绕性能测试分类、并发用户、吞吐量、响应时间等核心指标展开,并系统梳理了从问清需求、了解系统架构、分析测试点、工具选型、编写测试计划、环境搭建、测试实施到性能调优与报告输出的整体思路,其中理发店模式等比喻有助于理解并发用户的实际行为。资源包共1个PDF文件,大小约531KB,内容紧凑、便于随时查阅与打印学习。目前已有463人学习下载,适合作为入门阶段的系统梳理材料,也可在测试实施与调优过程中作为流程对照与概念速查的参考。
1. Web性能测试到底在测什么:从一份基础概念文档说起
很多人第一次接触 Web 性能测试,是从一份叫“基础概念”的 PDF 开始的。打开一看,满屏的 PV、UV、TPS、QPS、响应时间、并发数,每个字都认识,连起来却不知道先动哪个。更麻烦的是,真到项目里,开发说“接口很快啊”,运维说“服务器没压力”,老板说“用户就是嫌慢”,三方各说各话,没人能拿出一组让所有人闭嘴的数字。Web 性能测试要解决的,就是这件事:把“快不快”变成可量化、可复现、可归因的指标,让优化有靶子,让验收有依据。它适合后端开发、测试工程师、运维,以及任何需要为线上稳定性负责的人。这份基础概念文档的价值不在于教你用某个工具,而在于先把度量体系立住,否则后面压测跑出来的数字全是玄学。
2. 性能测试的指标坐标系:哪些数字真正决定结论
2.1 响应时间为什么不能只看平均值
响应时间是最容易被误读的指标。平均值把长尾抹平了,一个接口 90% 的请求 50ms 返回,10% 的请求 3s 返回,平均值可能只有 350ms,看起来很美,但真实用户里有十分之一在骂人。所以看响应时间必须看分位数,常见的是 P50、P90、P95、P99。P95 表示 95% 的请求在这个值以内完成,它比平均值更能暴露问题。
我一般会这样定基线:核心接口 P95 控制在 200ms 以内,P99 不超过 500ms;非核心接口 P95 放宽到 500ms。这个基线不是拍脑袋,而是结合业务容忍度反推的。比如一个下单接口,用户点完按钮等 1 秒还能接受,等 3 秒就会怀疑没点上,于是 P99 定在 1s 以内是合理的。
分位数怎么采集?压测工具基本都支持。以常见的 wrk 为例,它输出的 Latency Distribution 就是分位数分布:
# 用 wrk 对接口压测 30 秒,12 个线程,400 个连接 wrk -t12 -c400 -d30s --latency http://127.0.0.1:8080/api/order-t12是线程数,-c400是并发连接数,-d30s是持续时间,--latency打开延迟统计。输出里会看到 50%、75%、90%、99% 各档延迟。注意线程数不要超过 CPU 核数太多,否则压测机自己先成瓶颈,测出来的数字是压测机的,不是被测服务的。
2.2 吞吐量、并发数与 TPS 的换算关系
吞吐量描述单位时间能处理多少请求,常用 QPS(每秒查询数)或 TPS(每秒事务数)。并发数是同一时刻正在处理的请求数量。三者关系可以用一个近似公式表达:
TPS ≈ 并发数 / 平均响应时间(秒)
这个公式是估算用的,真实系统里响应时间会随并发上升而恶化,所以不能线性外推。它的价值在于帮你判断瓶颈方向:如果并发加到 200,平均响应时间从 50ms 涨到 500ms,TPS 反而没涨,说明系统已经饱和,再加并发只会让排队更长。
这里有个血泪经验:并发数不是越大越好。很多人压测时直接把并发拉到几千,结果错误率飙升,还以为是服务不行,其实是压测机端口耗尽或者被测服务连接池打满。正确的做法是从低并发开始,阶梯上升,观察 TPS 和响应时间的变化曲线,找到拐点。
2.3 错误率与资源水位:被忽略的两个否决项
错误率是硬指标。压测中只要出现非预期错误,比如 5xx、超时、连接拒绝,这轮结果就不能作为容量结论。常见做法是错误率超过 0.1% 就判定该并发档位不通过。
资源水位包括 CPU、内存、磁盘 IO、网络带宽。服务端 CPU 持续超过 80%、内存接近上限、磁盘 IO 等待高,都说明当前并发已经接近系统极限。压测时一定要同步采集这些数据,否则你只知道“慢了”,不知道“为什么慢”。
| 指标 | 建议阈值 | 采集方式 |
|---|---|---|
| P95 响应时间 | 核心接口 ≤ 200ms | 压测工具延迟分布 |
| 错误率 | ≤ 0.1% | 压测工具统计 |
| CPU 使用率 | 持续 ≤ 80% | 系统监控 |
| 内存使用率 | ≤ 85% | 系统监控 |
| 磁盘 IO wait | ≤ 10% | 系统监控 |
这张表可以直接作为压测报告的验收清单。注意阈值不是死的,要结合业务场景调整,比如报表导出接口 P95 到 2s 也正常。
3. 从零跑通一次 Web 性能测试:脚本、场景与数据
3.1 选压测工具:先看协议再看团队习惯
工具选型没有绝对优劣,关键看协议支持和团队上手成本。HTTP 接口压测,wrk、ab、JMeter、Locust 都能用。wrk 轻量、性能高,适合快速摸底;JMeter 图形化、插件多,适合复杂场景和报告输出;Locust 用 Python 写脚本,适合需要自定义逻辑的团队。
我一般这样分:临时验证一个接口,用 wrk 或 curl 循环;需要参数化、关联、断言、生成报告,用 JMeter;需要模拟复杂用户行为链,用 Locust。不要为了工具而工具,能说清楚数字就行。
3.2 写一个可复用的压测脚本
以 Locust 为例,写一个带参数化和思考时间的脚本:
from locust import HttpUser, task, between import random class OrderUser(HttpUser): # 模拟用户操作间隔 1 到 3 秒 wait_time = between(1, 3) def on_start(self): # 每个虚拟用户启动时先登录,拿到 token resp = self.client.post("/api/login", json={ "username": "test_user", "password": "test_pass" }) self.token = resp.json()["token"] @task(3) def query_order(self): # 权重 3,查询订单,带鉴权头 self.client.get("/api/order/list", headers={"Authorization": f"Bearer {self.token}"}, params={"page": random.randint(1, 10)}) @task(1) def create_order(self): # 权重 1,创建订单 self.client.post("/api/order/create", headers={"Authorization": f"Bearer {self.token}"}, json={"sku_id": random.randint(1000, 9999), "count": 1})wait_time模拟真实用户操作间隔,避免所有请求同一瞬间发出。@task(3)和@task(1)表示查询和创建的请求比例是 3:1,更接近真实流量模型。on_start里做登录,保证每个虚拟用户有独立会话。参数化用random生成,避免所有请求打同一个数据导致缓存命中率虚高。
启动命令:
# 启动 Locust,指定宿主和端口 locust -f locustfile.py --host=http://127.0.0.1:8080然后浏览器打开 Locust 界面设置并发数和增长速率。注意--host要和脚本里的路径拼起来能访问通,否则全是 404。
3.3 设计压测场景:基准、负载、稳定性怎么排
压测不是跑一次就完事,常见要跑三轮:
第一轮基准测试。单用户或低并发跑一遍,确认接口功能正常,记录单次响应时间作为参考下限。
第二轮负载测试。阶梯增加并发,比如 10、50、100、200、500,每档稳定跑 5 分钟,记录 TPS、响应时间、错误率、资源水位。找到 TPS 不再上升或错误率超标的拐点,这个拐点就是当前系统的容量上限。
第三轮稳定性测试。用容量上限的 70% 到 80% 并发,持续跑 2 到 8 小时,观察内存是否泄漏、连接是否耗尽、响应时间是否随时间劣化。很多问题只在长时间运行后暴露,比如连接池没回收、日志文件写满磁盘。
场景设计时要注意数据隔离。压测数据不要和线上真实数据混在一起,最好用独立库或带压测标记。否则压测产生的脏数据会污染业务,这个坑我踩过,清理起来非常麻烦。
4. 性能测试避坑:那些让结果失真的常见问题
4.1 压测机自己成了瓶颈
现象:并发加到 500 后,错误率突然飙升,但服务端 CPU 只有 30%。
原因:压测机端口耗尽或 CPU 跑满,请求根本发不出去。
解决:用ss -s看 TIME_WAIT 连接数,用top看压测机 CPU。如果压测机是瓶颈,换多台压测机分布式压测,或者减少压测机上的其他进程。Linux 下可以调大端口范围:
# 临时扩大本地端口范围,缓解 TIME_WAIT 堆积 sysctl -w net.ipv4.ip_local_port_range="1024 65535" sysctl -w net.ipv4.tcp_tw_reuse=1注意这些参数是压测机上的,不是服务端的,别改错机器。
4.2 缓存和连接池让第一轮数字虚高
现象:第一轮压测 TPS 很高,第二轮同样并发 TPS 掉了一半。
原因:第一轮有缓存预热和连接池冷启动,数据没代表性。
解决:每轮压测前先做预热,用低并发跑 1 到 2 分钟让缓存和连接池进入稳定状态,再开始正式采集。采集时丢弃前 30 秒数据。
4.3 只看服务端不看全链路
现象:服务端监控一切正常,但用户侧就是慢。
原因:慢在 DNS 解析、CDN、网关、数据库慢查询,这些不在应用服务端监控里。
解决:压测时同步抓全链路数据。至少要看网关的响应时间、数据库的慢查询日志、下游依赖的调用耗时。有条件就上分布式追踪,把一次请求经过的每个环节耗时都打出来。
4.4 压测数据污染业务库
现象:压测跑完,线上多了一批测试订单,客服被打爆。
原因:压测直接连了生产库,或者压测标记没做隔离。
解决:压测环境独立,数据库独立。如果必须连生产库,所有压测数据带统一前缀或标记字段,压测后按标记清理。更稳妥的做法是在数据库层做拦截,压测账号只能写压测表。
4.5 把平均响应时间写进报告
现象:报告写“平均响应时间 100ms”,评审时被质疑。
原因:平均值掩盖长尾,不能反映真实用户体验。
解决:报告里至少写 P50、P95、P99 三个分位数,并附上延迟分布图。如果只能写一个数,写 P95,不写平均值。
5. 让性能测试真正落地:从一次性压测到持续度量
性能测试最大的价值不是跑出一份报告,而是把度量变成习惯。我现在的做法是:核心接口的基准压测脚本进代码仓库,每次发版前自动跑一轮基准测试,P95 超过基线就阻断发布。这样性能问题在上线前就被拦住,而不是等用户投诉。
具体落地可以分三步。第一步,把压测脚本和测试数据准备好,脚本参数化,数据可重复生成。第二步,接入 CI 流水线,用低并发跑基准测试,只对比响应时间和错误率,不追求高并发。第三步,定期做全链路容量测试,比如每季度一次,用生产流量的倍数验证扩容方案。
验证压测结果是否可信,有个简单方法:看 TPS 和响应时间的关系是否符合预期。并发上升,TPS 先升后平,响应时间先稳后升,这是正常曲线。如果 TPS 随并发线性上升且响应时间不变,大概率是压测机没压到位或者服务端有缓存兜底。如果并发没加多少响应时间就爆了,检查连接池、线程池、数据库连接数这些容易打满的组件。
一个具体技巧:压测时用tcpdump抓包看 TCP 重传率。重传率高说明网络层有问题,这时候应用层的优化都是白费力气。
# 抓取压测期间的 TCP 重传,每 5 秒统计一次 tcpdump -i eth0 -s 96 -w /tmp/perf.pcap & sleep 30 kill %1 tcpdump -r /tmp/perf.pcap -nn | grep -i retrans | wc -l重传率超过 1% 就要先查网络,别急着改代码。
我自己踩过最深的坑,是早期做压测只看 TPS 不看错误率,结果报告里写“系统支持 5000 TPS”,上线后用户一多就雪崩。后来才明白,错误率超过 0.1% 的 TPS 数字没有任何意义,那只是系统在崩溃前最后的挣扎。现在我看压测报告,第一眼看错误率,第二眼看 P99,第三眼才看 TPS。这个顺序帮我省了很多后悔药。希望帮到你。
本文还有配套的精品资源,点击获取