第二章 性能度量与基准测试:关键性能指标、基准测试工具、负载模型设计、性能数据采集
性能优化这件事,说白了就是“先测量,再动手”。没有度量就没有优化——这句话我反复跟团队讲过。你连系统当前跑多快、瓶颈在哪都不知道,上来就改代码,那跟闭着眼开车没啥区别。
这一章,咱们就聊聊怎么给系统“体检”。我会把关键性能指标、基准测试工具、负载模型设计、数据采集这几个环节串起来讲。嗯,这里要注意:每个环节都有坑,我会把我在项目中踩过的雷也一并说出来。
2.1 关键性能指标(KPI)——你得知道看什么
性能指标不是越多越好。我见过有人把几十个指标堆在监控大屏上,结果出问题时根本不知道看哪个。我个人习惯,先盯住几个核心指标,其他的都是辅助。
2.1.1 响应时间(Latency)
用户发一个请求,到收到响应,花了多久。这个指标最直观。通常我们看三个值:
- 平均响应时间:容易受极端值影响,比如偶尔一次超时能把平均值拉高很多。
- 百分位响应时间:比如P99,意思是99%的请求都在这个时间内完成。这个比平均值更有参考价值。
- 最大响应时间:看系统最差情况的表现。
2.1.2 吞吐量(Throughput)
单位时间内系统能处理多少请求。常见单位:TPS(每秒事务数)、QPS(每秒查询数)。
吞吐量和响应时间其实是跷跷板关系。你压的请求越多,响应时间通常会变长。找到一个平衡点,才是关键。
2.1.3 资源利用率(Utilization)
CPU、内存、磁盘IO、网络带宽,这些资源用了多少?
- CPU跑满100%不一定是坏事,但如果是IO等待导致的CPU空闲,那就有问题了。
- 内存使用率过高,可能会触发Swap,性能直接跳水。
2.1.4 错误率(Error Rate)
请求失败的占比。比如HTTP 5xx错误、超时、连接拒绝等。错误率突然升高,往往意味着系统有严重问题。
| 指标类别 | 典型指标 | 说明 |
|---|---|---|
| 响应时间 | 平均、P50、P95、P99 | 反映用户体验 |
| 吞吐量 | TPS、QPS | 反映系统处理能力 |
| 资源利用率 | CPU、内存、磁盘、网络 | 反映资源瓶颈 |
| 错误率 | 5xx、超时、连接失败 | 反映系统稳定性 |
2.2 基准测试工具——选对工具,事半功倍
工具选不对,测试结果可能完全失真。我见过有人用单线程工具压测高并发系统,结果压测工具自己先成了瓶颈。下面是我常用的几款:
2.2.1 轻量级压测:wrk
wrk 是个命令行工具,基于事件驱动,单机就能压出很高的并发。适合快速验证接口性能。
# 用4个线程,保持100个连接,压测30秒
wrk -t4 -c100 -d30s http://your-api.com/endpoint
2.2.2 企业级压测:JMeter
JMeter 功能全面,支持图形界面、分布式压测、丰富的报告。适合复杂的业务场景。
- 可以录制脚本,模拟用户操作流程。
- 支持参数化、断言、监听器。
- 分布式部署时,一台控制机可以调度多台压力机。
2.2.3 数据库压测:sysbench
专门用来压测数据库的。支持MySQL、PostgreSQL等。可以测试OLTP(在线事务处理)和OLAP(在线分析处理)场景。
# 准备测试数据
sysbench --db-driver=mysql --mysql-user=root --mysql-password=xxx \
--mysql-db=test --table-size=1000000 oltp_read_write prepare
# 运行压测
sysbench --db-driver=mysql --mysql-user=root --mysql-password=xxx \
--mysql-db=test --threads=64 --time=60 oltp_read_write run
2.3 负载模型设计——别让测试脱离现实
负载模型设计,说白了就是模拟真实用户的行为。你想想看,如果真实场景是“用户登录后浏览商品再下单”,但你只压测一个“查询商品列表”的接口,那结果能准吗?
2.3.1 确定业务场景
先梳理出核心业务流程。比如电商系统:
- 用户登录(10%的请求)
- 搜索商品(30%的请求)
- 查看商品详情(40%的请求)
- 加入购物车(10%的请求)
- 提交订单(10%的请求)
这个比例不是拍脑袋定的,最好从生产环境的日志里统计出来。
2.3.2 设计并发模型
并发用户数不是越多越好。我建议分几个阶段:
- 基准测试:低并发,比如10个用户,看看系统基线性能。
- 负载测试:逐步增加并发,比如从10到100、200、500,观察性能变化。
- 压力测试:持续增加并发,直到系统出现瓶颈或崩溃,找到系统的极限。
- 稳定性测试:在某个并发下持续运行几小时甚至几天,看系统会不会内存泄漏、性能衰减。
2.3.3 数据准备
测试数据也要模拟真实情况。比如:
- 用户数据要有不同的等级、不同的历史订单量。
- 商品数据要有热门商品和冷门商品。
- 数据库里要有足够多的数据,不能只有几十条记录。
2.4 性能数据采集——把数据捞出来
压测跑起来了,数据怎么收?光看压测工具的报告是不够的,你得从系统层面、应用层面、数据库层面全方位采集。
2.4.1 系统层面
用 top、vmstat、iostat、netstat 这些命令,采集CPU、内存、磁盘、网络的数据。
# 每2秒采集一次CPU和内存数据
vmstat 2
# 采集磁盘IO数据
iostat -x 2
# 采集网络连接数
netstat -an | grep ESTABLISHED | wc -l
2.4.2 应用层面
应用日志里要打印关键信息:每个请求的处理时间、SQL执行时间、外部调用时间。我习惯用APM工具(比如SkyWalking、Pinpoint)来采集,它们能自动生成调用链,一眼就能看出慢在哪。
2.4.3 数据库层面
数据库的慢查询日志一定要开。还有 show processlist、show engine innodb status 这些命令,能帮你看到当前数据库在干什么。
-- 查看当前正在执行的SQL
SHOW FULL PROCESSLIST;
-- 查看InnoDB引擎状态(重点关注死锁、事务)
SHOW ENGINE INNODB STATUS\G
2.4.4 数据采集的注意事项
- 采样频率:别太高,否则采集工具本身会消耗资源。一般1-5秒一次就够了。
- 时间对齐:所有采集的数据要能对齐到同一个时间点,方便分析关联关系。
- 持久化:把数据存到时序数据库(比如Prometheus、InfluxDB)里,方便后续做趋势分析。
总结一下: 性能度量与基准测试,核心就是“选对指标、用对工具、建对模型、收对数据”。这四个环节环环相扣,缺一个都不行。
我个人习惯,每次压测前先画一个数据采集清单,把要看的指标、工具、命令都列出来。这样跑起来才不会手忙脚乱。