用 AI 设计压测场景:基准、负载、压力、稳定性与尖峰

「压到 5000 并发」不是一个场景,它只是一次没有对照的表演。压测跑不出结论,多半是场景没定义清楚:回答什么问题、用哪条加压曲线、跑多久、什么算通过,这四件事必须写在动手之前。让 AI 介入的正确位置,是先让它产出场景表,再让它把表翻译成脚本。

一、五类场景的定义

场景回答的问题加压曲线时长通过标准
基准(Benchmark)单个请求有多快,版本之间有没有退化恒定低并发(1~10),不爬坡1~3 分钟P99 波动 < 10%,与上次基线差 < 5%
负载(Load)设计容量下能否达标阶梯爬到目标后保持10~30 分钟目标 QPS 达成、P99 达标、错误率 < 0.1%
压力(Stress)上限在哪里,越界后怎么坏持续阶梯加,每档 2~5 分钟30~60 分钟找到拐点,破线后必须有恢复段观察回落
稳定性(Soak)内存、fd、连接池会不会累积上涨恒定在负载的 60%~70%2~12 小时内存斜率趋近 0,错误率无随时间上升趋势
尖峰(Spike)突发流量能否扛住并自动恢复秒级从基线跳到 310 倍,维持 13 分钟再回落10~20 分钟尖峰内错误率 < 1%,回落 5 分钟内回到基线

顺序也有讲究:基准 → 负载 → 压力 → 稳定性 → 尖峰。跳过基准直接做负载,后面所有的数字都没有参照物;跳过压力直接做稳定性,你不知道自己维持的是 60% 还是 95% 容量。

二、提示词:要场景表,不要脚本

角色:性能测试场景设计者,先输出表格,不要写脚本。
被测系统:订单查询服务,HTTP/1.1,接口 GET /api/v1/order/{id},鉴权用 Bearer token。
容量线索:单实例 4C8G,当前线上峰值 800 QPS,P99 约 60ms。
目标:找出单实例安全容量并给出上线余量建议。
要求:
  1) 输出场景表,列固定为:场景名 | 并发 | 目标 QPS | 时长 | 加压曲线 | 通过标准 | 观测项
  2) 五类场景(基准/负载/压力/稳定性/尖峰)每类至少一行,参数必须具体到数字
  3) 明确每一行「为什么是这个数字」,用一句话说明推算依据
  4) 指出哪些参数需要先做小规模试压才能定,不要给编造的依据
  5) 最后给出执行顺序与每类场景之间的间隔要求(环境复位、缓存清理、等待稳定)

要求「参数具体到数字」和「说明推算依据」这两条,能把大部分「并发 1000、时长 10 分钟」式的敷衍输出挡掉。

三、它应该产出的场景表

场景名并发目标 QPS时长加压曲线观测项
基准-单接口112 分钟恒定,无爬坡P50/P99、响应体大小、CPU
基准-版本对照112 分钟 ×2恒定,新旧版本各一次P99 差值、GC 次数
负载-设计容量5080020 分钟爬坡 2 分钟后保持QPS、P99、错误率、连接池占用
负载-带缓存混合80120020 分钟爬坡 5 分钟后保持缓存命中率、下游 QPS
压力-找拐点阶梯 20→400不限速40 分钟每 5 分钟翻一档,共 8 档P99 拐点、CPU、队列长度、GC 暂停
压力-恢复段005 分钟直接降为 0fd、连接池、内存是否回落到基线
稳定性-长跑305008 小时爬坡后恒定在 60% 容量内存斜率、fd 增长、错误率趋势
尖峰-秒杀式10→50080→400015 分钟30 秒内跳到 5 倍,维持 2 分钟后回落峰值错误率、超时数、恢复时间

这张表的每一行都能直接翻译成一段 k6 配置,这也是要求 AI「先出表」的价值:表格里的错误比脚本里的错误便宜得多。

四、把场景表翻译成加压曲线

// bench/scenarios.js:五类场景共用一份脚本,靠 SCENARIO 环境变量切换
import http from 'k6/http';
import { check } from 'k6';

const shapes = {
  // 基准:恒定单并发,只为拿可对比的基线数字
  benchmark: [{ duration: '2m', target: 1 }],
  // 负载:爬坡 2 分钟后长时间保持,观察稳态
  load: [
    { duration: '2m', target: 50 },
    { duration: '18m', target: 50 },
  ],
  // 压力:每 5 分钟翻一档,直到指标破线,末尾留恢复段
  stress: [
    { duration: '5m', target: 20 },
    { duration: '5m', target: 40 },
    { duration: '5m', target: 80 },
    { duration: '5m', target: 160 },
    { duration: '5m', target: 320 },
    { duration: '5m', target: 0 },
  ],
  // 尖峰:30 秒内跳到 5 倍并维持 2 分钟,再快速回落
  spike: [
    { duration: '2m', target: 10 },
    { duration: '30s', target: 500 },
    { duration: '2m', target: 500 },
    { duration: '30s', target: 10 },
    { duration: '5m', target: 10 },
  ],
  // 稳定性:爬坡后恒定长跑,重点看累积曲线而不是峰值
  soak: [
    { duration: '2m', target: 30 },
    { duration: '8h', target: 30 },
  ],
};

export const options = {
  scenarios: {
    run: {
      executor: 'ramping-vus',
      stages: shapes[__ENV.SCENARIO || 'load'],
      gracefulStop: '30s', // 留出在途请求收尾时间,否则错误率虚高
    },
  },
  thresholds: {
    http_req_failed: ['rate<0.001'],
    http_req_duration: ['p(99)<100'],
  },
};

export default function () {
  const res = http.get(`${__ENV.BASE}/api/v1/order/1001`, {
    headers: { Authorization: `Bearer ${__ENV.TOKEN}` },
  });
  check(res, { 'status is 200': (r) => r.status === 200 });
}
for s in benchmark load stress spike soak; do
  k6 run -e SCENARIO=$s -e BASE=http://10.0.0.12:8080 -e TOKEN="$T" \
    --summary-export="summary-$s.json" bench/scenarios.js
  sleep 300   # 场景之间留复位时间:清缓存、等连接池回落、确认 fd 回到基线
done

压力场景的 stages 是并发曲线而不是 QPS 曲线:并发翻倍、QPS 不涨,就是拐点所在;想固定 QPS 做压力测试,把执行器换成 ramping-arrival-rate,用 rate 描述到达率。

五、通过标准要写进阈值,而不是写在文档里

场景阈值写法备注
基准http_req_duration: ['p(99)<80']基线本身要存档,用于跨版本比对
负载p(99)<100 + http_req_failed: ['rate<0.001']达标即可,不追求极限
压力不设阈值,改为人工判读拐点阈值会让脚本提前中断,反而不利于找上限
稳定性p(99)<150 + 内存增长趋势人工判读阈值只兜住明显劣化,长跑看斜率
尖峰http_req_failed: ['rate<0.01']尖峰内放宽到 1%,但恢复时间必须单独记录

常见坑

坑现象做法
没有基准就做负载数字无参照,无法判断好坏每类压测前先跑一次 2 分钟基准
场景之间不复位上一轮缓存、连接池、GC 状态污染下一轮场景间隔 5 分钟,必要时重启服务
稳定性只跑 30 分钟累积型问题(fd、内存泄漏)看不出来至少 2 小时,长连接类建议 8 小时以上
尖峰没有回落段无法判断是硬扛还是缓慢劣化峰后必须保留 5 分钟基线观察窗口
压力场景设了阈值脚本在拐点前中断,拿不到上限压力场景关闭阈值,靠人工判读
所有场景共用一份数据缓存命中率虚高,压的是缓存不是服务按场景准备不同位点与热度的数据
只记录峰值数字丢掉了曲线和拐点导出原始数据,把 QPS、延迟、资源画在同一时间轴

小结:五类场景各自回答一个不同的问题——基准给参照、负载验容量、压力找上限、稳定性看累积、尖峰测恢复;让 AI 先输出固定列(场景名 / 并发 / 目标 QPS / 时长 / 加压曲线 / 通过标准 / 观测项)的场景表,要求参数具体到数字并说明推算依据,再把表翻译成 stages;执行顺序固定为基准在前、压力居中、稳定性与尖峰在后,每轮之间留复位时间,通过标准尽量写成阈值,压力场景则留给人工判读。长连接与 IM 场景的具体参数可对照 im-ws 目录第 18 章与 im-system 目录第 26 章。

笔记加载中…