全链路压测体系:压测目标设定与容量评估,压测数据隔离,压测流量模型设计

聊到全链路压测,很多团队上来就开干。我见过不少项目,压测工具配好了,脚本写完了,结果压出来的数据根本没法用。为什么?因为目标没定清楚,数据没隔离好,流量模型也跟真实场景对不上。

说白了,全链路压测不是跑个脚本就完事。它是一套系统工程。今天我就把这块掰开揉碎了讲,重点说三件事:目标怎么定、容量怎么算、数据怎么隔离、流量模型怎么设计

一、压测目标设定:别拍脑袋,要算清楚

我习惯把压测目标分成三层:业务目标 → 技术指标 → 压测场景。你想想看,如果老板说“双十一要扛住”,那具体扛多少?是100万QPS还是500万?

1.1 业务目标拆解

举个例子。某电商平台大促,业务目标是“1小时内完成1000万笔订单”。那技术指标怎么算?

  • 平均每秒订单数:1000万 ÷ 3600秒 ≈ 2778 笔/秒
  • 峰值系数:一般取2~3倍,按3倍算 ≈ 8334 笔/秒
  • 每个订单涉及3次接口调用(下单、支付、回调)→ 峰值QPS ≈ 25000

核心公式:

目标QPS = (业务总量 ÷ 时间窗口) × 峰值系数 × 接口调用次数

1.2 技术指标设定

我个人习惯用“三个九”原则:

指标 目标值 说明
成功率 ≥ 99.9% 压测期间请求成功率
P99延迟 ≤ 500ms 99%的请求在500ms内完成
错误率 ≤ 0.1% 超时、5xx等错误

注意: 我曾经在项目中遇到过,目标定得太高,结果压测环境根本跑不到那个量级。后来发现是压测机本身成了瓶颈。所以目标设定时,也要考虑压测基础设施的承载能力。

二、容量评估:从单机到集群的推演

容量评估不是玄学。我一般分三步走:单机摸底 → 线性扩展验证 → 集群容量推算

2.1 单机摸底

先压单台机器,找到它的极限。比如一台4C8G的实例,压测发现:

  • CPU到80%时,QPS约5000
  • 再往上压,延迟开始飙升
  • CPU到95%时,QPS反而下降到4000(因为上下文切换开销)

所以这台机器的安全水位是:5000 × 0.7 = 3500 QPS。留30%的余量应对突发。

2.2 线性扩展验证

单机3500,那10台是不是35000?不一定。我见过最坑的情况是,加到8台时性能反而下降了。为什么?因为共享资源(数据库、缓存、消息队列)成了瓶颈。

我的经验: 每次加机器后,都要重新压一次。如果扩展效率低于80%,说明架构有问题。比如数据库连接池没调大,或者缓存分片不均匀。

2.3 集群容量推算

假设单机安全水位3500 QPS,扩展效率85%,目标QPS是25000:

所需机器数 = 25000 ÷ (3500 × 0.85) ≈ 8.4 → 取9台

嗯,这里要注意。这个公式只适用于无状态服务。有状态服务(比如Session粘滞)要单独评估。

三、压测数据隔离:影子库 vs 影子表

数据隔离是压测里最容易出问题的地方。我见过有人直接在线上库压测,结果把用户数据搞乱了。那叫一个惨。

3.1 影子库方案

简单说,就是给压测流量单独建一个数据库。比如线上库叫db_online,影子库叫db_shadow

  • 优点: 完全隔离,互不影响
  • 缺点: 成本高,需要额外维护一套库

我建议在压测规模大、数据量大的场景用影子库。比如双十一压测,数据量几十TB,影子表根本放不下。

3.2 影子表方案

在同一个库里,建一套带后缀的表。比如orders表,影子表叫orders_shadow

-- 线上表
CREATE TABLE orders (
  id BIGINT PRIMARY KEY,
  user_id BIGINT,
  amount DECIMAL(10,2),
  create_time DATETIME
);

-- 影子表
CREATE TABLE orders_shadow LIKE orders;

压测时,通过中间件或ORM拦截,把SQL路由到影子表。我习惯在请求头里加一个x-shadow: true的标记,网关层根据这个标记做路由。

关键点: 影子表要跟线上表结构完全一致。包括索引、分区、存储引擎。不然压测结果不准。

3.3 数据清理策略

压测结束后,影子数据必须清干净。我曾经遇到过,压测数据没清完,结果第二天线上报表里多出了几百万条测试订单。

我的做法是:

  1. 压测前记录影子表的基线数据量
  2. 压测后对比增量,按批次删除
  3. 用定时任务兜底,24小时后自动清理

四、压测流量模型设计:模拟真实用户行为

流量模型设计不好,压测结果就是自欺欺人。你想想看,如果所有请求都是均匀的,那跟真实场景差太远了。

4.1 流量特征分析

我一般从三个维度分析:

  • 时间分布: 白天高、晚上低?还是凌晨有波峰?
  • 接口比例: 登录、浏览、下单、支付,各占多少?
  • 参数分布: 热门商品被频繁访问,冷门商品几乎没人看

4.2 流量模型实现

以JMeter为例,我会这样设计:

// 1. 登录接口:占10%的流量
// 2. 浏览商品:占40%的流量
// 3. 加购物车:占20%的流量
// 4. 下单:占20%的流量
// 5. 支付:占10%的流量

// 使用随机控制器,按比例分配
// 参数用CSV文件,模拟不同用户、不同商品

嗯,这里要注意。真实场景中,用户不是同时操作的。所以要用思考时间来模拟用户停顿。我一般设成100~500ms的随机延迟。

4.3 流量模型验证

压测跑起来后,我会对比线上真实流量和压测流量的分布。如果发现某个接口的比例偏差超过10%,就要调整模型。

一个小技巧: 用Kibana或Grafana,把线上流量和压测流量画在同一张图上。一眼就能看出模型准不准。

五、总结

全链路压测,说白了就是三个字:真、准、稳

  • 真: 流量模型要真实,别用均匀分布糊弄自己
  • 准: 容量评估要算清楚,留足余量
  • 稳: 数据隔离要做好,别把线上搞崩了

我做了这么多年SRE,最深的体会是:压测不是为了证明系统没问题,而是为了提前发现问题。所以别怕压出问题,怕的是压不出来问题。

好了,这一章就聊到这儿。下一章我们讲压测工具选型和脚本编写,到时候我会分享一些我踩过的坑。