性能测试:生产系统压测的风险与控制策略
生产压测一直是性能测试里最敏感、也最容易引发争议的话题之一。
支持生产压测的判断通常是:
- 只有生产环境最真实
- 不在生产压,很多风险根本看不到
反对它的人也有很强的理由:
- 一旦失控,代价太大
- 用户、数据、第三方依赖都可能被误伤
这两边都没有完全错。
生产压测真正难的,不在“要不要做”这么简单,而在:
如果真要做,怎样把风险降到一个可控、可接受、可快速止损的范围内。
所以更愿意把生产压测理解成一场受严格约束的风险实验,而不是一次“更接近生产流量的普通压测”。
一、生产压测真正的风险,不只是“把系统压挂”
一提生产压测,脑子里只有一种风险:
- 系统会不会被打挂
但从真实项目经验看,更常见、也更隐蔽的风险其实包括:
- 误伤真实用户流量
- 写入真实脏数据
- 触发真实风控、告警、补偿、发券、发消息链路
- 放大第三方调用成本
- 把缓存、消息、数据库状态污染到生产
也就是说,生产压测的风险不只是“慢”和“挂”,更可怕的是“业务污染”和“外部副作用”。
如果这一层不先想清楚,生产压测很容易变成一次代价昂贵的误操作。
二、生产压测首先要解决的,不是施压方式,而是隔离方式
如果要只保留一个原则,那就是:
生产压测更稳的顺序是先解决隔离,再考虑加压。
常见的隔离思路包括:
- 压测流量标识
- 压测账号池
- 压测数据空间
- 压测白名单
- 压测消息主题或影子队列
- 影子表、影子库、影子索引
重点不在于形式多高级,而在于是否能回答这几个问题:
- 压测流量能不能和真实用户请求区分开
- 压测写入的数据能不能回收
- 压测触发的副作用能不能被限制在可控范围
如果这三件事做不到,生产压测基本就不该开始。
三、生产压测最容易出事故的地方,是副作用链路没有提前盘清楚
很多系统不是一个请求结束就完了。
一次生产请求背后可能会连带触发:
- 短信
- 邮件
- 推送
- 工单
- 积分
- 优惠券
- 风控
- 异步补偿
- 第三方支付或回调
如果这些副作用链路没有在压测前逐个确认清楚,生产压测最容易发生的事情不是“性能问题”,而是“业务事故”。
所以通常会要求在压测前列一张非常明确的副作用清单:
- 哪些链路会被真实触发
- 哪些要屏蔽
- 哪些要走影子通道
- 哪些可以保留但必须限量
这一步通常比写脚本更重要。
四、更推荐的生产压测推进顺序:先探测,再扩面,再升压
生产压测最忌讳的方式,就是:
- 方案没收紧
- 隔离没验证
- 监控还没盯稳
- 一上来就打峰值
这类操作一旦出事,通常连回头空间都很小。
更倾向的顺序通常是:
1. 低流量探测
目的:
- 验证压测流量有没有被正确识别
- 验证压测标识、影子数据、隔离策略有没有生效
- 验证告警、监控和止损链路是否可用
2. 小范围放量
目的:
- 观察系统和依赖是否出现意外副作用
- 确认真实生产流量和压测流量是否发生冲突
3. 分段升压
目的:
- 在可观测前提下逐步逼近目标负载
- 识别退化拐点
- 保留及时止损空间
生产压测不是越快越好,而是越可控越好。
五、生产压测必须提前定义“谁有权停止、什么情况下停止”
这是生产压测里最容易被忽略、但极其重要的一点。
会认真准备脚本和方案,却没有认真准备“怎么停”。
通常要求在执行前就明确:
1. 停机线
例如:
- 错误率超过某阈值
- 关键依赖资源超阈
- 用户投诉开始出现
- 第三方服务异常
2. 决策人
也就是谁能明确拍板:
- 暂停
- 继续
- 终止
如果这件事不提前约定,现场一旦出异常,最常见的情况就是:
- 每个人都看到了风险
- 但没人敢先喊停
这时候风险往往会比系统本身的问题扩散得更快。
六、在项目里最看重的几类生产压测控制策略
1. 压测流量标识需要贯穿链路
不能只在入口层加个 header 就算完。
更理想的方式是让它在日志、监控、调用链、下游服务里都可识别。
否则一旦出问题,你甚至分不清:
- 当前看到的异常到底是生产真实流量,还是压测流量带来的
2. 数据需要可回收
如果压测会写生产数据,那你至少要回答:
- 这些数据如何标记
- 这些数据如何清理
- 清理失败怎么办
否则压测结束以后,脏数据会持续污染业务分析和后续流程。
3. 第三方调用需要提前设边界
很多系统最容易出问题的,不是自己扛不住,而是把第三方打穿、打超费、打进风控。
生产压测前,这一层必须单独确认。
4. 监控要提前进入“压测视角”
不能压测开始了才临时找图。
更好的方式是提前明确:
- 入口流量图
- 业务成功率
- 核心依赖资源
- 压测流量识别维度
七、在项目里踩过的几个典型坑
坑 1:只隔离了入口,没有隔离下游副作用
表面上看请求是压测流量,实际上消息、通知、补偿还是走了真实链路。
这种问题非常危险,因为现场一开始可能根本看不出来。
坑 2:压测账号是独立的,但写数据还是进了真实业务域
用了压测账号并不代表就万事大吉,如果订单、工单、消息、日志等仍然写在真实域里,污染照样会发生。
坑 3:监控没做压测流量切分,结果现场只看到“全局异常”
这类情况一出现,现场会非常混乱,因为没人能快速判断:
- 是压测在伤系统
- 还是本来就有线上波动
坑 4:没有明确停机线,现场靠感觉判断
这是我最不推荐的做法。
生产压测最怕“再观察一下”,因为很多风险扩散并不会给你太多缓冲时间。
八、排查生产压测方案是否靠谱时,通常先看什么
1. 先看隔离设计
确认:
- 压测流量是否可识别
- 压测数据是否可回收
- 副作用链路是否已处理
九、生产压测前会直接拉一张执行清单
生产压测不能只靠口头确认。
如果真要做,通常会拉一张显式清单,执行前逐项勾掉。
例如:
| 检查项 | 是否完成 | 备注 |
|---|---|---|
| 压测流量 header 已贯穿入口和下游 | 是/否 | 包括日志和调用链 |
| 压测账号池已准备 | 是/否 | 可区分真实用户 |
| 写入数据可标记、可回收 | 是/否 | 已验证清理脚本 |
| 短信、邮件、推送已屏蔽或走影子通道 | 是/否 | 防止副作用扩散 |
| 第三方接口限流边界已确认 | 是/否 | 避免外部成本和风控 |
| 监控面板已切好压测视角 | 是/否 | 可区分压测流量 |
| 停机线和决策人已确认 | 是/否 | 现场可立即止损 |
这张表没有技术门槛,但极其有用。
因为生产压测很多事故,本质上都是“以为确认了,其实没人真确认”。
十、更常用的一套生产压测推进节奏
如果隔离设计已经准备好,通常也不会一上来就放大流量。
更常见的节奏是:
- 先打极小流量,验证流量标识和副作用隔离
- 再做 5 到 10 分钟小范围放量
- 观察用户指标、业务指标和依赖指标都稳定后,再进入正式升压
- 每次升压前都做一次“是否继续”确认
现场通常会把继续条件写得非常具体:
- 当前错误率仍低于阈值
- 没有真实用户投诉
- 第三方调用没有异常放大
- 压测流量与真实流量仍可清晰区分
如果这些条件里有一条解释不清,就不继续加压。
十一、真出问题时怎么止损
生产压测不是不能出问题,而是必须准备好问题一出现就能收住。
通常会预设下面几个动作:
- 立即停止入口压测流量
- 冻结当前阶段参数和监控截图
- 确认异常是否仍在持续
- 如果异常仍在,回看是否有副作用链路未被切断
- 先恢复业务,再讨论根因
这里有个很现实的原则:
生产压测现场,止损优先级永远高于根因分析。
根因可以会后慢慢看,但真实业务和真实用户不能拿来等分析结论。
2. 再看监控和止损机制
确认:
- 关键指标是否能实时观测
- 谁来拍板停止是否明确
3. 再看施压策略
确认:
- 是不是分阶段推进
- 有没有低流量探测环节
4. 最后才看脚本与工具
因为生产压测最大的风险很多并不是来自脚本本身,而是来自边界没控住。
结语
生产压测的核心从来不是“敢不敢压”,而是能不能在真实用户、真实数据、真实依赖都在线的情况下,把这场实验设计得足够可控。
更准确地说,生产压测最少要做到:
- 流量可识别
- 数据可回收
- 副作用可隔离
- 风险可观测
- 现场可止损
如果这些基础都没补齐,生产压测很容易变成一次高风险冒险;
只有把隔离、监控、回退和停机线都设计好,它才有资格成为一场可控验证。