seanwalter
返回手册列表
🔍

性能压测与性能分析实战手册

面向 Web 接口、数据库、缓存、消息队列、微服务和云原生环境的性能测试实战参考,覆盖压测方案设计、工具选型、脚本编写、监控采集、瓶颈定位、优化验证与测试报告输出。

12 章节9 类工具5 类实战场景报告模板
📈

性能测试概览

目标与适用场景

性能测试不是简单地“把并发打上去”,而是通过可控的压力模型验证系统在不同负载下的响应能力、稳定性、资源消耗和容量边界。一次有效的性能测试,应该回答以下问题:

  • 系统在目标并发下是否能稳定提供服务?
  • 核心接口的平均响应时间、P95、P99 是否满足业务要求?
  • 系统最大吞吐量是多少?拐点在哪里?
  • 瓶颈出现在应用、数据库、缓存、网络、磁盘还是第三方服务?
  • 当前资源配置能支撑多少用户量、订单量或请求量?
  • 优化前后性能是否有可量化提升?

性能测试适用场景

场景目标关注点
新系统上线前验证系统是否达到上线容量要求吞吐量、响应时间、错误率、资源水位
大促或活动前评估高峰流量承载能力峰值 QPS、限流降级、缓存命中率
架构改造后验证改造是否带来性能收益优化前后对比、资源成本变化
故障复盘后复现瓶颈并验证修复效果瓶颈链路、容量边界、稳定性
容量规划推算机器数量、连接池、队列长度单机能力、横向扩展效率、成本
🎯

核心性能指标

QPS / P95 / 资源水位

请求与吞吐指标

指标含义说明
QPSQueries Per Second,每秒查询数常用于 HTTP 查询接口、搜索接口、读多写少场景
TPSTransactions Per Second,每秒事务数常用于下单、支付、写入类业务事务
RPSRequests Per Second,每秒请求数HTTP 压测工具常见输出指标
吞吐量单位时间内系统处理的数据量或请求量可用请求数、字节数、消息数、订单数衡量
并发数同一时间正在处理或保持连接的用户/请求数并发数不等于 QPS,需要结合响应时间理解

响应时间指标

指标含义判断方式
Avg RT平均响应时间容易被极端值掩盖,只适合做粗略参考
P5050% 请求的响应时间低于该值代表普通用户体验
P9090% 请求的响应时间低于该值代表大多数用户体验
P9595% 请求的响应时间低于该值接口性能验收常用指标
P9999% 请求的响应时间低于该值用于观察长尾延迟和稳定性问题
Max RT最大响应时间用于辅助判断异常请求,不应单独作为验收标准

稳定性与资源指标

  • 错误率:HTTP 5xx、业务失败码、超时、连接失败占比。
  • CPU 使用率:长期高于 80% 需要关注,长期 90% 以上通常存在风险。
  • 内存使用率:关注 RSS、Heap、缓存、Swap、OOM 风险。
  • 磁盘 IO:关注 IOPS、吞吐、await、util、日志写入压力。
  • 网络:关注带宽、连接数、TIME_WAIT、丢包、重传。
  • 数据库:关注慢 SQL、锁等待、连接数、Buffer 命中率、主从延迟。
  • 缓存:关注命中率、内存碎片、热 Key、大 Key、淘汰策略。
🧪

常见测试类型

基准 / 负载 / 压力 / 稳定性
类型目标典型做法
基准测试获得系统在固定条件下的基础性能数据固定并发、固定数据集、固定环境,记录基线结果
负载测试验证目标业务负载下系统是否稳定按预期流量模型逐步加压,观察 SLA 是否达标
压力测试寻找系统极限和性能拐点持续增加并发或 QPS,直到错误率上升或响应时间恶化
稳定性测试验证系统长时间运行是否可靠按中高负载持续运行 4 小时、8 小时、24 小时或更久
容量测试评估当前配置可支撑的业务规模结合峰值流量、资源水位和扩容策略进行推算
突刺测试验证瞬时流量冲击下的保护能力短时间内快速升高并发,观察限流、熔断、降级效果
🧭

标准测试流程

从目标到复测

1. 明确测试目标

  • 目标接口或业务链路是什么?
  • 目标 QPS/TPS、并发数、响应时间是多少?
  • 允许的错误率是多少?
  • 测试环境是否等比例接近生产?
  • 本次测试是上线验收、瓶颈定位、容量评估还是优化对比?

2. 准备测试环境

  • 确认测试环境配置:CPU、内存、磁盘、网络、容器限制。
  • 确认应用配置:线程池、连接池、JVM 参数、Node.js 进程数。
  • 确认数据库配置:最大连接数、索引、缓存、慢查询日志。
  • 确认中间件配置:Redis、MQ、Nginx、网关、限流规则。
  • 提前配置监控面板,避免压测后才发现没有数据。

场景设计要素

设计项示例
用户行为登录 1 次、查询商品 10 次、创建订单 1 次
请求比例读接口 80%,写接口 20%
数据分布热门商品 20% 承担 80% 请求
思考时间用户两次操作之间等待 1 到 3 秒
断言规则HTTP 200 且业务 code 为 0 才算成功

3. 执行压测与复测

  1. 先用小流量进行脚本冒烟,确认请求成功、断言正确、数据可用。
  2. 再进行阶梯加压,例如 50、100、200、500、1000 并发。
  3. 每个压力档位保持足够时间,至少覆盖缓存预热、GC、连接池稳定过程。
  4. 记录每个档位的 QPS、RT、错误率和资源水位。
  5. 出现大量错误、资源打满或业务异常时,及时停止并保留现场。
  6. 优化后使用同样脚本、数据、环境和压力模型复测,避免结论失真。
🛠

常用压测工具

ab / wrk / k6 / JMeter / Locust
工具适合场景特点推荐程度
ab快速验证单个 HTTP 接口简单、轻量、参数少临时测试可用
wrk高并发 HTTP 压测性能强,支持 Lua 脚本推荐
k6接口压测、CI 集成、脚本化场景JavaScript 编写脚本,结果清晰强烈推荐
JMeter企业级复杂场景压测图形化、插件多、学习资料丰富推荐
LocustPython 场景化用户行为压测代码表达能力强,适合复杂流程推荐
hey轻量 HTTP 压测命令简单,输出直观临时测试推荐
sysbenchCPU、内存、磁盘、MySQL 基准测试适合系统与数据库基准评估推荐
redis-benchmarkRedis 性能测试Redis 官方自带工具推荐
iperf3网络带宽与吞吐测试定位网络瓶颈常用推荐

ab 快速压测

bash
# 1000 个请求,100 并发
ab -n 1000 -c 100 http://127.0.0.1:3000/api/products

# POST JSON 请求
ab -n 1000 -c 50   -p body.json   -T "application/json"   http://127.0.0.1:3000/api/orders

wrk 高并发压测

bash
# 8 线程,200 连接,持续 60 秒
wrk -t8 -c200 -d60s http://127.0.0.1:3000/api/products

# 输出延迟分布
wrk -t8 -c200 -d60s --latency http://127.0.0.1:3000/api/products

k6 阶梯加压脚本

javascript
import http from "k6/http";
import { check, sleep } from "k6";

export const options = {
  stages: [
    { duration: "1m", target: 50 },
    { duration: "3m", target: 200 },
    { duration: "1m", target: 0 }
  ],
  thresholds: {
    http_req_failed: ["rate<0.01"],
    http_req_duration: ["p(95)<500"]
  }
};

export default function () {
  const res = http.get("https://example.com/api/products");

  check(res, {
    "status is 200": (r) => r.status === 200,
    "body not empty": (r) => r.body.length > 0
  });

  sleep(1);
}
bash
k6 run load-test.js
🌐

HTTP 接口压测实战

GET / POST / 登录态

GET 接口压测

bash
wrk -t4 -c100 -d60s --latency   "https://example.com/api/products?page=1&size=20"

POST JSON 接口压测

javascript
import http from "k6/http";
import { check } from "k6";

export const options = {
  vus: 100,
  duration: "2m",
  thresholds: {
    http_req_failed: ["rate<0.01"],
    http_req_duration: ["p(95)<800"]
  }
};

export default function () {
  const payload = JSON.stringify({ productId: 1001, quantity: 1 });
  const params = {
    headers: {
      "Content-Type": "application/json",
      "Authorization": "Bearer your-token"
    }
  };

  const res = http.post("https://example.com/api/orders", payload, params);

  check(res, {
    "status is 200": (r) => r.status === 200,
    "business success": (r) => r.json("code") === 0
  });
}

登录态压测注意事项

登录态压测不要让所有虚拟用户共用同一个账号,否则会引入锁、风控、Session 覆盖、缓存热点等干扰。建议准备账号池,并让每个虚拟用户使用独立账号或独立 Token。

  • 只校验 HTTP 200,不校验业务返回码,会掩盖真实失败。
  • 所有请求使用同一条测试数据,会导致缓存命中率虚高。
  • 没有设置超时时间,慢请求堆积后容易误判系统吞吐。
  • 压测机性能不足时,瓶颈可能出现在客户端而不是服务端。
  • 只压单接口,不压真实业务链路,结论通常偏乐观。
🗄

数据库与缓存压测

MySQL / Redis

MySQL 基准测试

bash
# 准备测试数据
sysbench oltp_read_write   --mysql-host=127.0.0.1   --mysql-port=3306   --mysql-user=root   --mysql-password=your-password   --mysql-db=test   --tables=10   --table-size=100000   prepare

# 执行读写压测
sysbench oltp_read_write   --mysql-host=127.0.0.1   --mysql-user=root   --mysql-password=your-password   --mysql-db=test   --tables=10   --table-size=100000   --threads=32   --time=300   run

Redis 压测

bash
# 100 并发,100000 请求,测试 set/get
redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000 -t set,get

# 指定 value 大小
redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000 -d 1024 -t get,set

# 测试 pipeline
redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000 -P 16 -t get,set

数据库压测关注点

  • 慢 SQL 数量是否增加,索引是否命中,是否出现全表扫描。
  • 连接池是否耗尽,是否存在连接泄漏。
  • 锁等待、死锁、事务耗时是否异常。
  • Buffer Pool 命中率是否下降,主从复制延迟是否扩大。
  • 磁盘 IO 是否成为瓶颈。
📡

监控与数据采集

主机 / 应用 / 数据库 / 链路

Linux 常用监控命令

命令用途示例
top / htop查看 CPU、内存、进程top
vmstat查看 CPU、内存、上下文切换vmstat 1
iostat查看磁盘 IOiostat -x 1
sar采集系统历史性能数据sar -u 1
ss查看网络连接ss -s
pidstat查看进程级 CPU、内存、IOpidstat -p <pid> 1
free查看内存free -h
dmesg查看内核与 OOM 信息dmesg -T | tail

压测期间建议采集的数据

  • 压测工具输出:QPS、P95、P99、错误率、请求总数。
  • 应用监控:接口耗时、错误日志、线程池、连接池、GC。
  • 主机监控:CPU、内存、磁盘 IO、网络连接。
  • 数据库监控:慢 SQL、连接数、锁等待、缓存命中率。
  • 缓存监控:命中率、内存使用、QPS、大 Key、热 Key。
  • 链路追踪:慢 Span、下游调用耗时、外部依赖耗时。

Prometheus 常用观察指标

promql
# HTTP 请求 QPS
sum(rate(http_requests_total[1m])) by (path)

# HTTP P95 响应时间
histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le, path))

# HTTP 错误率
sum(rate(http_requests_total{status=~"5.."}[1m])) / sum(rate(http_requests_total[1m]))

# 容器 CPU 使用率
sum(rate(container_cpu_usage_seconds_total[1m])) by (pod)

# 容器内存使用
container_memory_working_set_bytes
🔎

性能瓶颈定位

曲线解读与优化方向

瓶颈判断口诀

  • QPS 上不去,CPU 打满:优先看应用计算、序列化、锁竞争、热点代码。
  • QPS 上不去,CPU 不高:优先看 IO、数据库、外部依赖、连接池、锁等待。
  • RT 升高,错误率不高:可能是排队、慢 SQL、GC、下游延迟。
  • RT 升高,错误率升高:可能是资源耗尽、连接失败、超时、限流。
  • 平均响应时间正常,P99 很高:重点排查长尾请求、锁、GC、网络抖动。
  • 单机性能正常,集群性能不线性:关注负载均衡、共享资源、数据库瓶颈。

常见瓶颈与处理方向

瓶颈类型表现排查方向优化方向
CPU 瓶颈CPU 长期高位,Load 升高火焰图、热点函数、线程状态减少计算、缓存结果、异步化、扩容
内存瓶颈内存持续上涨,GC 频繁,OOMHeap Dump、对象分配、缓存大小修复泄漏、限制缓存、调整 GC
数据库瓶颈慢 SQL 增多,连接池耗尽执行计划、索引、锁等待、事务建索引、改 SQL、分库分表、读写分离
缓存瓶颈命中率下降,Redis CPU 高热 Key、大 Key、过期策略本地缓存、拆分 Key、限流、预热
网络瓶颈延迟高、重传、连接失败带宽、连接数、丢包、DNS连接复用、压缩、就近访问、扩带宽
线程池瓶颈请求排队,RT 增加,CPU 不高队列长度、活跃线程、拒绝策略调参、拆池、异步处理、限流

压测曲线解读

  • 理想阶段:并发增加,QPS 线性增加,RT 稳定。
  • 临界阶段:QPS 增长变慢,RT 开始上升,资源接近高水位。
  • 拐点阶段:QPS 不再增长,RT 快速上升,错误率开始增加。
  • 崩溃阶段:大量超时或 5xx,服务不可用,资源耗尽或保护策略触发。

容量评估一般不要取系统极限值,而应取拐点之前的稳定区间,并预留安全水位。例如系统极限为 1000 QPS,建议线上容量按 600 到 700 QPS 规划,再配合限流、降级和扩容策略。

🏢

企业实战场景

从登录到微服务链路

登录接口压测

  • 准备独立账号池,避免单账号锁定或风控。
  • 关注密码校验、Token 生成、Session 写入、Redis 访问。
  • 检查错误率中是否包含验证码、限流、账号锁定等业务失败。
  • 关注数据库用户表查询、登录日志写入、审计日志异步队列。

商品查询接口压测

  • 区分热门商品、普通商品、无库存商品。
  • 关注缓存命中率、搜索服务耗时、数据库回源比例。
  • 避免所有请求命中同一个商品导致结果过于乐观。
  • 观察 P99 是否因缓存击穿或慢查询出现长尾。

下单链路压测

  • 链路通常包含库存校验、价格计算、优惠券、订单写入、消息发送。
  • 必须设计测试数据清理策略,避免库存被打空后大量业务失败。
  • 关注数据库事务、行锁、唯一索引冲突、MQ 积压。
  • 压测后需要核对订单数据一致性。

消息队列消费能力测试

  • 分别测试生产速度、消费速度和堆积恢复能力。
  • 关注消费者线程数、批量消费大小、失败重试、死信队列。
  • 记录堆积量从峰值恢复到正常水位所需时间。
  • 确认扩容消费者是否能线性提升消费能力。

微服务链路压测

  • 关注网关、认证服务、业务服务、数据库、缓存、外部依赖的完整链路。
  • 必须开启链路追踪,否则很难定位慢点。
  • 检查超时配置是否逐层递减,避免请求长时间占用资源。
  • 验证限流、熔断、降级是否符合预期。
📝

性能测试报告模板

结论 / 环境 / 场景 / 建议

测试结论

项目填写说明
测试系统填写系统名称、版本、测试环境
测试目标例如核心接口 P95 小于 500ms,错误率小于 1%
测试结论通过 / 不通过 / 有条件通过
最大稳定吞吐例如 800 QPS,P95 420ms,错误率 0.2%
系统瓶颈例如数据库 CPU 高、订单表行锁等待明显
优化建议例如补充索引、拆分热点数据、增加缓存预热

环境信息

  • 应用版本、Git Commit、配置文件版本。
  • 服务器规格:CPU、内存、磁盘、网络。
  • 部署方式:物理机、虚拟机、Docker、Kubernetes。
  • 数据库与中间件版本、规格和参数。
  • 压测机规格、网络位置、压测工具版本。

测试场景记录

场景并发/速率持续时间成功率P95P99QPS/TPS结论
商品查询200 并发10 分钟99.9%180ms350ms1200通过
创建订单100 并发10 分钟99.2%680ms1200ms300需优化

压测检查清单

压测前 / 中 / 后

压测前

  • 已明确测试目标、验收标准和停止条件。
  • 已确认压测范围,不会误压生产或第三方服务。
  • 已准备独立测试数据、账号池和清理方案。
  • 已配置应用、主机、数据库、缓存、链路追踪监控。
  • 已完成小流量冒烟,确认脚本和断言正确。
  • 已通知相关团队,避免误报故障。

压测中

  • 逐步加压,不直接打满系统。
  • 实时观察错误率、P95、P99 和资源水位。
  • 发现异常及时记录时间点、压力档位和监控截图。
  • 触发停止条件时立即停止压测。
  • 不要在同一轮压测中频繁修改配置,否则结果不可对比。

压测后

  • 导出压测结果、监控数据、日志和链路追踪。
  • 清理测试数据,恢复环境配置。
  • 整理瓶颈结论和优化建议。
  • 优化后使用相同模型复测。
  • 沉淀容量基线,为后续上线和扩容提供依据。