AI 参与压测的坑:幻觉参数、压测机瓶颈与缓存假象
AI 让压测脚本的产出速度快了一个数量级,代价是引入了新的失败模式:脚本跑得很顺,结论却是错的。下面七类坑按「危害程度 × 出现频率」排列,每条都给判断信号与规避动作。共同点是——它们都不报错。
坑一:编造工具参数(幻觉 flag)
AI 会自信地写出并不存在的命令行参数,例如给 wrk 加一个 --ramp-up、给 ghz 加一个拼错的 --concurrency-timeout。这类参数有时被工具静默忽略,有时直接报错,最坏情况是被工具当成另一个含义使用了。
| 怎么发现 | 怎么避免 |
|---|---|
执行前用 <工具> --help 逐项核对每个参数是否真实存在 | 让 AI 同时输出「参数核对命令」,自己跑一遍再压 |
| 观察输出中是否出现 warning 或未识别的选项 | 脚本里对参数做白名单校验,禁止直接粘贴未经核对的命令 |
| 对比参数与实际行为:设了 200 并发但连接数只有 10 | 压测前用小档位试跑,确认参数真的生效 |
wrk --help | grep -F -- '--latency'
k6 run --help | grep -F 'ramping-arrival-rate'
ghz --help | grep -F -- '-c'
凡 AI 给出的工具参数,最可靠的处理方式是只保留官方帮助里出现过的选项;其余写法自己补齐并注明来源。
坑二:把压测机瓶颈当成服务端瓶颈
4 核的压测机上跑 wrk,压到 3000 QPS 时延迟飙升,很容易被写成「服务端容量拐点在 3000 QPS」。实际上拐点在压测机上:客户端 CPU 打满、网卡软中断堆积、本地端口耗尽,都会让服务端看起来很慢。
| 判断信号 | 规避动作 |
|---|---|
压测机 CPU 超过 70%,或 si 软中断占比高 | 压测机核数不低于被测实例核数,或使用多台分布式压测 |
出现大量 TIME_WAIT、bind: address already in use | 开启连接复用,调大本地端口范围,避免短连接压测假象 |
客户端报 Socket errors: connect,服务端监控却平静 | 明确记录压测机水位,报告里单列一列压测机 CPU |
| 服务端延迟曲线与压测机 CPU 曲线高度同步 | 先排除客户端瓶颈,再谈服务端拐点 |
sar -u 1 5 # 压测机 CPU 与软中断
sar -n DEV 1 5 # 网卡吞吐是否接近上限
ss -s # TIME_WAIT 与端口占用
坑三:缓存与预热造成的假象
第一次压测(冷缓存)与第二次压测(热缓存)结果可能相差数倍。反复压同一批用户与同一批商品 ID,缓存命中率趋近 100%,测出来的是缓存而不是系统。
| 判断信号 | 规避动作 |
|---|---|
| 同一脚本连续压两次,第二次 QPS 明显更高 | 固定预热流程:统一预热 60 秒并丢弃预热数据 |
| 压测期间缓存命中率接近 100% | 报告中记录命中率,并用生产真实命中率折算容量 |
| 参数全为同一 ID,DB 几乎零负载 | 参数按生产分布随机化,覆盖冷热数据与不存在的键 |
| 压测前手动清缓存,结果与生产差距大 | 冷热两轮都做,分别给出结论 |
坑四:数据倾斜与数据量不足
用 1000 行数据压出 5000 QPS,换成 800 万行可能只剩 800 QPS:索引深度、缓存淘汰、锁粒度全都会变。把所有请求打在同一行上,还会人为制造行锁热点,测出的并发能力远低于真实水平。
| 判断信号 | 规避动作 |
|---|---|
| 压测数据量比生产小一个数量级 | 数据量按生产规模准备,至少保证索引层级一致 |
| 参数集中在少数几个热点键 | 按生产分布生成参数,注明分布模型 |
| 压测中出现大量锁等待 | 检查是否所有请求更新同一行,改为分片或随机化主键 |
| DB 的扫描行数远小于生产 | 用真实数据副本脱敏,而不是手造少量数据 |
坑五:限流与熔断导致的误判
网关上配了限流,超出的请求被快速拒绝并返回 429;熔断打开时下游调用直接失败返回。这两种情况下延迟都很「漂亮」,因为最慢的路径被提前掐断了。
| 判断信号 | 规避动作 |
|---|---|
| 错误码分布里 429 或特定业务码占比高 | 压测前确认限流阈值,或临时放宽到不触发的水位并记录 |
| 吞吐在某个档位突然不再增长但延迟不涨 | 先怀疑限流、熔断、连接数上限这三个「隐形天花板」 |
| 熔断器状态在压测期间发生变化 | 采集熔断器状态指标,纳入报告附录 |
| 错误率高但 P99 反而降低 | 快速失败掩盖了排队,按错误率扣除有效吞吐 |
坑六:只报平均值
平均值是压测报告里最没有信息量的数字。平均值 30ms 而 P99 260ms 的系统,用户体验由后者决定。
| 判断信号 | 规避动作 |
|---|---|
| 报告只有平均延迟或只有吞吐 | 强制要求 P50/P90/P99/P99.9 与最大值同表呈现 |
| 平均值与 P50 差距过大 | 核对统计口径:是否把超时请求排除在统计外 |
| 未记录错误率 | 吞吐必须与错误率成对出现,非零错误率的档位不得作为容量依据 |
坑七:配置不一致与「优化过的压测环境」
为了跑出好看的曲线,脚本里关掉鉴权、把日志级别调到 ERROR、把超时设成 60s、只压读接口。这些改动让压测结果与生产脱节。
| 判断信号 | 规避动作 |
|---|---|
| 压测环境与生产在实例规格、参数、依赖拓扑上有差异 | 用配置清单逐项对齐,差异项写进报告 |
| 生产是集群,压测只压单实例且中间件是独占的 | 明确标注范围,多实例竞争场景单独补测 |
| 超时与重试配置与生产不同 | 保持与生产一致,或说明改动带来的影响方向 |
| 只压了读接口 | 按生产读写比例混合场景,写入路径单独压 |
压测前对齐清单:
实例规格与数量 / GOMAXPROCS 或 JVM 参数 / 日志级别 / 鉴权开关
超时与重试 / 连接池大小 / 中间件规格与拓扑 / 数据量与分布
限流与熔断阈值 / 缓存预热状态 / 压测机规格与数量
AI 用得好与用得差的区别
| 用法 | 结果 |
|---|---|
| 让 AI 写脚本,自己核对参数与配置对齐 | 效率提升,结论可信 |
| 让 AI 直接给结论,自己只做执行 | 幻觉参数与错误归因一起进了报告 |
| 让 AI 列「可能原因」,自己去采集证据验证 | 定位加速,且每一步可追溯 |
| 把压测环境差异交给 AI 判断影响 | 它看不到你的环境,需要你把差异逐条列出 |
小结:AI 参与的压测最怕「无报错但结论错」——幻觉参数要靠 --help 逐项核对,压测机瓶颈要靠客户端水位排除,缓存与数据倾斜要靠预热流程、真实数据量与参数随机化解决,限流熔断要靠错误码分布识别,平均值必须换成分位,最后用一份环境对齐清单保证压测结果能迁移到生产。