原文链接:https://mp.weixin.qq.com/s/rGnACe_ITzFG3bANvGo0XQ
1. 性能测试完整流程详解
1.1. 需求分析与目标确认
性能测试的目的不是要跑压测工具,而是想通过相应的手段识别系统的瓶颈,保障系统在目标场景下的稳定性和相应能力。如果没有明确的性能目标,测试结果将没有意义,优化方向也会迷失。
常见误区包括:
- “把接口压一压” 就是性能测试
- 只关注 TPS 或 QPS,而忽略资源使用、响应时间、可用性
- 没有明确的业务目标或上线场景支撑
性能测试的需求并不是测试或者研发拍脑袋决定的,通常来源于以下几个方面:
| 来源 | 内容 |
|---|---|
| 业务需求文档 | 日活量、访问高峰期预测、使用人群 |
| 历史数据 | 上一版本的 TPS/QPS、慢查询数据 |
| 运维指标 | CPU、内存、磁盘、带宽的报警阈值 |
| 架构设计文档 | 分布式部署、限流策略、缓存设计 |
| SLA/SLO 要求 | 如:99% 接口响应时间<200ms, 99.9% 的可用性等 |
1.2. 计划与场景设计
性能问题的暴露往往是一个逐层放大的过程:接口没有问题,链路之间可能有问题;链路没问题,全链路的资源争抢、瓶颈、依赖就可能暴露问题。
因此我们需要从最小颗粒度的接口开始,逐层抽象到整个业务系统,最终设计出覆盖全面、风险可控、逐层定位的性能测试场景。
1.2.1. 单接口压测
目的:验证单个接口在不同负载下的性能极限和稳定性
应用场景:
- 新开发或重构的接口
- 接口性能瓶颈排查
- 网关或中间层性能验证
设计要素:
- 固定参数、构造 mock 数据、动态参数,需要根据接口实现评估
- 并发阶梯上升测试(如 10→100→500 QPS)
- 分析 TPS、响应时间、错误率、资源使用情况
1.2.2. 单链路压测
目的:验证某一完整业务流程在负载下的性能表现
链路定义:多个接口组成一个完整用户动作路径(前后端协作逻辑链)
应用场景:
- 重点核心链路性能保障(如发送消息链路)
- 新业务流程上线前的性能评估
- 依赖系统集成验证
设计要素:
- 明确业务路径中每一个接口
- 统一会话上下文(如 token、cookie)
- 保证链路间逻辑与数据关联完整
- 并发压测模拟典型业务负载
1.2.3. 多链路组合压测
目的:模拟系统在真实运行中多个业务并发执行的场景
应用场景:
- 高并发、多业务并行的系统(如收发消息、云文档编辑等)
- 验证资源争抢、锁冲突、数据库并发能力
- 典型日常负载/高峰期混合负载模拟
设计要素:
- 链路权重配置(如收发消息 40%,文档编辑 30%,文档分享 30%)
- 设置不同业务比例组合并发
- 引入高峰期行为模拟
1.2.4. 全链路压测
目的:模拟生产环境真实高负载下系统全景运行状态,验证系统承压能力、瓶颈位置、异常恢复能力
应用场景:
- 上线前全链路压测
- 灰度环境大促演练
- 微服务架构压力传播路径验证
设计要素:
- 构造真实生产级数据(用户、商品、订单等)
- 覆盖所有核心业务路径
- 后台任务、消息队列、缓存等全部纳入
- 引入 Chaos、限流、降级等机制联动演练
典型示例:
- 模拟双 11 零点流量冲击整个系统
- 从用户访问首页→浏览→下单→支付→发货的全链路,打通缓存、搜索、DB、MQ、第三方接口等
关键关注点:
- 系统限流、熔断、降级机制是否生效
- 整体资源使用(带宽、内存、CPU、连接池)
- 异常恢复能力(如服务节点故障、网络波动)
1.3. 环境与数据准备
1.3.1. 环境准备
环境准备的原则:
- 真实性优先:环境应尽量接近生产,模拟出真实负载下的行为和瓶颈
- 隔离性保障:确保测试行为不会影响真实用户和业务数据
- 成本可控:压测环境不必 100% 按照生产资源规格建设,可适当缩小规模,但要评估比例影响
- 监控完备:监控能力必须和生产持平甚至更强,否则无法正确定位性能瓶颈
| 环境类型 | 特点 | 适用场景 |
|---|---|---|
| 生产环境压测(影子压测) | 数据最真实,但风险高 | 核心系统灰度验证 |
| 准生产环境(beta) | 与生产相似,推荐首选 | 上线前性能验证 |
| 独立压测环境 | 资源可控,安全性高 | 新功能验证、接口 |
1.3.2. 测试数据准备
性能测试的数据准备,不是随便造几条数据,而是要覆盖真实业务场景 + 满足测试维度多样性 + 可重复使用。
1. 数据维度设计
| 维度 | 说明 | 示例 |
|---|---|---|
| 用户数据 | 有效用户量、登录态 | 生成 x 万用户 |
| 群聊/私聊结构 | 群成员分布、群数量 | x 人大群,x 人小群 |
| ... | 内容敏感 | ... |
2. 数据构造方法
- 离线构造脚本(推荐):使用 Python/Golang 编写批量注册/造数脚本
- 数据库直接导入(需谨慎):适合大体量测试数据
- Mock 服务:对依赖系统未就绪部分进行 mock 返回
- 动态预热脚本(常用):每次压测前动态登录、获取 token、构建上下文
1.4. 脚本开发
脚本开发是连接 “性能测试需求分析” 与 “压测执行” 的桥梁环节。无论是单接口压测,还是复杂的多链路全链路压测,脚本都是整个过程的执行载体。
1.4.1. 输入准备
| 输入项 | 说明 |
|---|---|
| 接口定义 | 接口 URL、请求方式、Headers、参数结构等 |
| 用例场景 | 关键接口链路、参数组合、依赖顺序 |
| 数据依赖 | 例如接口依赖登录的 token |
| 响应断言 | 是否成功(status code、字段内容等) |
| TPS 目标 | 用于设计线程数、请求频率的依据 |
1.4.2. 脚本设计方式(单接口→全链路)
-
单接口:
- 验证接口的稳定性与性能瓶颈(如登录、搜索)
- 设计并发参数:用户、QPS、持续时间等
- 搭配断言 + 数据文件驱动测试(如 CSV)
-
单链路脚本开发:
- 模拟一次完整操作流程,如:登录→搜索商品→下单→查询订单
- 关键点:参数关联(如 token、订单 ID)、请求顺序与依赖、用户行为还原
-
多链路/业务流程脚本开发:
- 支持多个角色(买家/卖家/系统任务等)
- 并行执行多个链路压测,体现真实业务压力结构
1.4.3. 可维护性与复用性建议
- 参数化设计:将业务参数抽出,支持脚本复用
- 模块化结构:按链路或模块拆分,便于组合使用
- 封装通用函数:如签名计算、断言逻辑、动态提取
- 支持回归验证:加入功能正确性断言,提前发现错误响应
- 敏感信息隔离:Token、密码参数放置于 config 文件或 secrets 环境变量中
1.5. 测试执行
根据预设场景和目标,稳定、可控地施加压力,并采集关键性能指标,辅助问题定位与性能评估。
1.5.1. 执行前准备 Checklist
| 项目 | 说明 |
|---|---|
| 压测环境准备 | 环境隔离,配置一致,监控联通 |
| 数据初始化 | 测试数据准备好,并且数据状态正常 |
| 服务监控接入 | Prometheus/Grafana/APM 工具等 |
| 日志、链路追踪打开 | 包括 Nginx、应用服务、数据库慢查询 |
| 观察指标定义 | RT、TPS、错误率、CPU、内存、GC 等 |
| 脚本冒烟 | 小流量压测验证逻辑正确性 |
| 依赖方沟通 | 告知被测系统负责人,避免误报警 |
1.5.2. 流量控制与压测模式
1. 常见压测流量模型
| 模型 | 说明 | 示例 |
|---|---|---|
| 恒定并发 | 模拟固定用户数持续操作 | 50 并发持续 10 分钟 |
| 阶梯增长 | 模拟高峰来临过程 | 每 5 分钟增加 10 并发 |
| 峰值冲击 | 快速打满系统能力 | 高并发短时间强打压 |
| 混合场景 | 多接口/多链路同时发压 | 收发消息,打开文件并行 |
| 波浪式 | 模拟系统高峰低谷流量模式 | 凌晨压测流量 1 倍,工 10 倍 |
2. 发压策略建议
- 从小流量逐步升压,观察系统响应变化;
- 每个阶段稳定观察 10~30 分钟,确保性能趋势稳定;
- 压测过程中持续观察:RT 是否持续上升?错误率是否激增?后台是否出现线程阻塞、慢查询、GC 卡顿等?
1.6. 结果监控与收集
压测过程的核心是采数据、看变化。以下的数据只是一小部分的维度,实际上的问题排查可能会涉及更多性能数据的分析与评估对比。
1.6.1. 监控维度
| 维度 | 指标 | 工具 |
|---|---|---|
| 应用层 | RT、TPS、错误率、接口 P95/P99 | JMeter、Locust |
| 系统层 | CPU、内存、GC、负载、磁盘 IO、网络 IO | Prometheus、Grafana |
| 数据库 | 连接数、慢查询、QPS、锁等待、缓存命中率 | MySQL Dashboard |
| 中间件 | Kafka TPS、Redis QPS、MQ 消息堆积 | 业务自研平台 |
| 链路追踪 | 某一请求经过的服务链路耗时分布 | SkyWalking、Jaeger |
1.6.2. 异常识别与瓶颈定位
| 问题类型 | 特征 | 定位手段 |
|---|---|---|
| 接口超时 | RT 飙高,JMeter 报超时 | 链路追踪 + 服务日志 |
| 错误率升高 | TPS 下跌,5xx、4xx 增多 | 日志分析 + 接口返回码 |
| CPU 撑满 | TPS 持平但延迟高 | top/Grafana 观测线程 |
| GC 卡顿 | RT 波动大,GC 次数/耗时高 | jstat/GC 日志分析 |
| 数据库瓶颈 | 连接数满、锁等待、慢 SQL | explain+slowlog 分析 |
| 缓存穿透/雪崩 | Redis 请求激增,DB 被打爆 | Redis 监控/fallback |
1.7. 分析与报告
在这里的核心目标是:
1. 汇总并分析压测期间的关键性能指标
2. 发现性能瓶颈,定位异常
3. 评估系统是否满足业务性能目标
4. 为优化和容量规划提供决策依据
5. 对外形成结构清晰、结论明确的性能测试报告
1.7.1. 压测结果的核心指标分析
1. 压测数据指标
| 指标 | 说明 | 分析关注点 |
|---|---|---|
| TPS/QPS | 每秒处理请求数 | 是否达到预期目标 |
| 响应时间(RT) | 平均、P90、P95、P99 | 是否符合 SLA 要求 |
| 成功率 | 有效响应数/总请求数 | 是否出现错误 |
| 错误率 | 5xx/超时/断言失败等 | 哪些类型最多?集中在哪? |
| 并发数 | 实际活跃线程数 | 压力是否真实落到系统 |
2. 系统服务资源
| 指标 | 说明 | 分析关注点 |
|---|---|---|
| 系统资源 | CPU、内存、IO、网络流量、连接数等 | 有无资源瓶颈 |
3. 中间件核心性能指标
Redis(缓存)
| 指标 | 说明 |
|---|---|
| instantaneous_ops_per_sec | 每秒命令执行数(类似 QPS) |
| keyspace_hits/misses | 命中率,命中低代表缓存不生效 |
| latency | 响应时间,高峰期时尤为重要 |
| used_memory_rss, used_memory_peak | 实际占用内存,是否接近上限 |
| connected_clients | 当前连接数,是否稳定,是否打满 |
| evicted_keys, expired_keys | 是否频繁淘汰,是否存在热点键被清除问题 |
MySQL(数据库)
| 类别 | 指标 |
|---|---|
| 性能 | Queries, QPS, Slow_queries |
| 性能 | Threads_running |
| 资源 | CPU, Buffer pool usage, IO wait |
| 连接 | Threads_connected, Max_used_connections |
| 异常 | InnoDB row lock wait, Deadlocks |
1.8. 优化与验证
“优化与验证”是承上启下的关键模块,目标是根据压测分析结果,驱动系统调优并验证优化是否有效,确保最终上线版本性能稳定、可支撑预期业务量。
以后再细聊吧
2. 性能测试场景设计精髓
性能测试的成败,很大程度上取决于场景设计的科学性与贴合实际业务的能力。设计合理的场景不仅能发现真实瓶颈,还能评估系统是否具备承接未来增长的能力。
2.1. 识别关键业务场景(用户旅程)
常见识别方式:
- 业务日志分析(如接口调用量、慢接口)
- 产品功能矩阵分析
- 用户核心操作路径(注册→浏览→下单→支付)
- 报警日志/问题记录回溯(历史抖动点)
- 新业务或核心流程变更部分优先保障
示例:IM 系统
- 登录鉴权→获取好友列表→获取历史消息→发消息→收消息→群发
2.2. 设计负载模型
负载模型决定了压测目标和策略。应根据业务发展阶段、测试目的不同,匹配不同类型的压测模型。
2.2.1. 负载测试(阶梯式、波浪式)
目的:模拟真实业务压力下的系统表现
- 阶梯式增长(线性上涨,观察系统是否能逐步抗压)
- 波浪式压力(高低起伏模拟真实日常高峰、波谷)
适用:日常容量验证、上线前回归测试等
2.2.2. 压力测试(摸高)
目的:突破系统瓶颈上限,发现故障点
- 施加超过正常预期的负载
- 观察 TPS 崩溃点、错误率、系统反应(降级 or 崩溃)
适用:容量规划、服务保护策略验证
2.2.3. 稳定性测试
目的:验证系统在长时间运行下的稳定性
运行 8h~72h 不等,重点关注内存泄漏、连接泄漏、数据积压,其实我们跑的是 7*24 小时。
2.2.4. 并发测试
目的:验证系统对并发突发请求的处理能力
一般用于秒杀、拼团等突发流量场景
要求场景中包含随机性、冲突性(如同一个商品库存扣减)
2.3. 模拟真实用户行为
2.3.1. 用户分布
- 模拟不同角色/客户端/地区/终端比例
- 如 IM:普通用户:运营账号=95:5;移动端:Web 端=9:1
避免单一用户压爆系统,影响结果真实性
2.3.2. 数据参数化
- 用户 ID、Token、订单号等避免重复数据导致缓存命中、幂等化绕开问题。
- 支持动态生成、从 CSV/数据库中加载。
2.3.3. 接口关联
- 登录→获取 token→用 token 访问后续接口
- 场景逻辑需要前后数据串联,如订单创建后的订单 ID→查询支付状态
2.3.4. 设计有效的断言和事务
- 判断接口响应是否成功、关键字段是否存在
- 防止 “压测跑通了,业务其实报错”
- 建议使用响应码 + 响应值校验双保险
浙公网安备 33010602011771号