
1. 代号“测试1111”是什么一次测试任务的解构实录先说说这个标题的由来。如果你在测试圈待过一定时间应该见过很多类似的代号“测试8888”、“测试demo”、“test_final_v2”这类命名泛滥的测试任务。它们的共同特点是命名随意但需求往往不简单。“测试1111”这个代号听起来像临时起意但在实际项目中它一般指代两类场景要么是双十一大促前的全链路演练要么是某个版本发布前的四轮主流程回归测试。今天我按前者来写因为这种场景下“1111”的含义更清晰四个“1”分别代表一次全链路走查、一轮性能压测、一套监控预案、一场复盘归档对应大促前质量保障的四个核心动作。先把这个项目的整体轮廓摆出来。大促测试和日常功能测试完全是两种思路。日常测试关注功能正确性大促测试关心的是“扛不扛得住、崩了能不能快速恢复、用户路径通不通”。所以“测试1111”这种代号背后真正要回答的问题有三个系统在峰值流量下的吞吐上限是多少核心交易链路有没有单点风险异常发生时团队能不能在第一时间定位并止血。这个项目适合测试工程师、测试负责人、以及负责大促维稳的后端和运维同学参考。我做这个项目时最大的感触是大促测试的性质决定了它不能像普通迭代那样按用例逐条过而必须先把“风险边界”画清楚。边界之外的东西可以暂时不测边界之内的东西宁可重复测三遍也不能漏一遍。这个思路贯穿了整个项目的设计和执行下面按照每个环节逐一拆开讲。2. 四个“1”的含义拆解为什么是两次业务走查加性能与预案2.1 一次全链路走查从用户点击到支付回调第一个“1”指全链路走查覆盖用户在大促期间的完整操作路径。普通测试会把这条路拆成几十条独立用例但大促测试必须把它们拼回一条完整的路因为单模块正常不代表串联后没有问题。我具体验证的主链路包括进入首页轮播大促入口、商品详情页加载秒杀价、加购成功后库存锁定、提交订单进入支付环节、支付成功后回调异步通知订单中心、订单状态回写用户端、最后是优惠券/积分同步到账。这条链路在任何一台测试机上跑一遍只需要几分钟但真实价值在于找出跨模块的协议和状态同步问题。尤其是支付回调这种异步场景测试环境网络抖动不常见但生产环境在流量高峰时回调延迟和乱序是常态所以全链路走查必须刻意模拟延迟和重复通知。这里有个测试设计的细节每个关键节点我都在日志里埋了 traceId通过一个固定前缀把一次完整请求串起来。排查问题时不用猜直接按 traceId 从接入层翻到数据库哪个环节耗时超过阈值一目了然。日常测试可能不需要这么较真但大促期间必须这样做因为故障分秒必争。2.2 一次性能压测找到系统的天花板而不是证明系统没问题第二个“1”是性能压测。这个环节我踩过最大的坑是“为了压测而压测”——领导要求提供一份报告于是压了半小时画了几条曲线得出“系统稳如泰山”的结论。这种测试毫无价值因为压出来的数据可能离真实瓶颈十万八千里。真正的压测要找的是“四板斧”指标最大吞吐量、平均响应时间、错误率拐点、资源饱和点。我习惯按梯队加压而不是直接拉满先按日常峰值的30%跑10分钟观察各项指标基线然后跳到60%再跑10分钟重点看响应时间的p99是否线性上涨接着压到预估峰值的100%此时主要盯错误率和 GC 频率最后再冲到120%找系统的崩溃临界点。每一步之间留5分钟观察恢复情况确认系统在流量回落后能自行恢复而不是处在假死状态。压测环境我强烈建议独立搭建不要拿日常开发联调环境充数。如果实在资源有限至少要保证数据库是独立实例因为联调环境里别的团队在跑任务性能数据全是脏的。我在这个项目里就是因为在共用环境压过一次结果一个定时任务突然触发把压测数据全部污染浪费了一整天。2.3 一套监控预案90%的故障靠监控发现只有10%靠用户反馈第三个“1”是监控预案的检查和演练。大多数团队不是没有监控而是监控项太多太散告警刷屏后反而没人认真看。大促前我做的第一件事是梳理监控大盘把内容收敛成“红黄绿”三级视图红色是直接影响交易的项比如下单失败率超过1%、支付成功率低于99%、核心接口响应时间超过500ms黄色是边缘但有潜在影响比如某类券的发放量异常、某个渠道的流量占比突然变化绿色是普通指标比如整体PV、UV、CPU使用率。告警阈值也做了调整。平时接口响应时间300ms可能就告警但大促期间必须分级预发环境阈值降低便于前置发现问题生产环境阈值适当放宽避免告警风暴。真正重要的一定是“变化率”而不是“绝对值”——比如某个接口成功率从99.9%掉到99%绝对值看起来还行但变化率说明可能出事了。我后来把监控大盘的核心指标都改成了“同比上一小时变化率”这比固定阈值要实用得多。预案演练很多人会忽略而这个项目里我专门安排了一次15分钟的突击演练。操作很简单让运维手动把商品服务的两个节点做网络隔离看监控会不会自动告警、值班人能不能在3分钟内发现问题、预案文档里的回滚命令是否还能用。结果是真发现问题了——预案文档里的一个注册中心地址已经失效代码分支也早被清理。这种演练的价值不是“证明系统高可用”而是发现预案与实际环境的偏差。2.4 一场复盘归档把测试数据变成下一次的起跑线第四个“1”是复盘归档。别小看这一步我见过太多团队在项目结束后直接散了连一份完整的测试总结都没留下。下一次做同类项目时又从头开始踩坑。归档的内容不是简单贴一份测试报告而是包含四件套全链路走查的用例清单及每次修改的记录、压测的原始数据和趋势图、监控预案的最终版和演练过程记录、所有遇到的风险点及处理方案的完整描述。尤其要记录“事前不知道、事后回头看才发现”的问题类型。比如我这次项目里发现优惠券系统在库存不足时有一个静默降级策略平时几乎不触发但大促高峰期因为并发太高频繁触发有一段时间用户领券无提示但实际没发出去。这类问题不归档下次再做类似场景时还是会掉进同一个坑。3. 工具选型与参数配置没有万能的工具只有合适的组合3.1 压测工具怎么选从 JMeter 到 Locust 的取舍性能压测工具选择直接决定了测试的效率和结果可信度。JMeter 和 Locust 是我用得最多的两个不能说哪个绝对更好关键是看场景。JMeter 的优势是图形化界面、插件生态丰富、脚本录制方便适合没有太多代码基础的同学快速上手Locust 的优势是纯 Python 脚本控制可以写很复杂的用户行为逻辑分布式压测时资源调度更灵活适合需要模拟真实用户思维路径的场景。我做“测试1111”这个项目时核心链路涉及购物车、库存锁定、支付回调多个模块既有简单的 HTTP 接口也有一些需要保持会话状态的复杂操作所以我用了 Locust。写一个用户类定义 on_start 方法模拟用户进入大促会场然后在 task 装饰器下定义浏览商品、加购、下单、支付这几个动作每个动作之间加随机思考时间。这样压出来的流量模式更接近真实用户比单纯用 JMeter 循环跑单个接口要可信得多。如果团队里没有熟悉代码的人或者被测系统是标准 HTTP 接口不需要复杂场景编排JMeter 也完全够用。我补一句工具选型别追求最新最炫稳定和团队熟悉度才是第一优先级。大促前临时换工具的风险极大光脚本调试就能吃掉一天时间。3.2 压测参数设置的几个关键数字压测参数设置直接决定结果是否可信我总结出几个必须认真对待的数字。第一是并发用户数和 QPS 的关系。很多人误以为这两者等价其实不是。同样1000个并发用户如果每个用户两次请求之间思考3秒实际 QPS 可能只有300多如果脚本里没有思考时间发的是压力请求1000并发对应的 QPS 可能接近1000。所以压测报告里必须同时标明这两个数字只写“支撑1000并发”没有参考意义。第二是线程数/协程数的起步值。我习惯从“预估峰值的30%”起步不是随便拍脑袋。比如业务方预估峰值是5000 QPS那么第一步压1500 QPS跑10分钟看系统状态稳定后再跨到3000 QPS跑10分钟然后到5000 QPS跑15分钟最后冲到6000 QPS烧5分钟找崩溃点。每一步边压边观察而不是一次性把目标拉满。第三是超时时间的设置。压测脚本里的 HTTP 超时时间最好设为业务侧真实超时时间的两倍。如果业务侧超时配置是3秒脚本里就设6秒避免因为脚本过早断开导致响应时间数据失真。这里有个常见误区有人把超时时间设得很长等着一堆超时请求把线程池占满结果是工具本身的瓶颈而系统根本没到极限。第四是压测数据的准备量级。库存类的数据不能只有几条否则压力全集中在同一行记录的行锁上。我在项目里提前用脚本造了10万条商品数据和100万条用户数据分散在表里压测时随机取用。这样测出来的性能数据才是系统真实水平而不是针对某一条热点数据的极端场景。3.3 监控与日志采集全链路追踪是排查问题的骨架监控层面的工具我建议必须能覆盖三个层次基础设施层、应用层、业务层。基础设施层看 CPU、内存、磁盘 IO、网络应用层看 JVM 堆内存、GC 频率、线程池状态、Tomcat 连接数业务层看订单量、支付成功率、优惠券发放量。判断问题时要跨层对比比如业务侧看到下单成功率掉了应用层显示线程池活跃数异常高基础设施层发现 CPU 吃满那大概率是流量超过系统容量。只有一层的数据说明不了问题。全链路追踪工具有条件的团队建议上 SkyWalking 或 Zipkin没条件也一定要在日志里规范 traceId 的透传。我这次项目里用的就是日志中透传 traceId 的方式压测时把采集到的日志按 traceId 聚合每一跳的耗时都在日志里清晰可见。有一次定位下单接口的耗时过高问题就是通过 traceId 链路发现瓶颈不在下单服务本身而是它调用库存服务时因为连接池配置太小导致线程等待。4. 实操详解全链路走查与压测执行的完整记录4.1 第五轮全链路走查的操作清单整个项目期间全链路走查一共做了五次。前两轮是每迭代功能完成后做的快速走查第三轮是封板后的完整走查第四轮在压测前做了一次预热第五轮是压测结束后为了确认系统恢复状态做的一次收尾走查。五轮走查的侧重点完全不同不能混为一谈。第五轮走查我列了22条主流程用例覆盖从大促活动页进入、商品列表排序、详情页价格展示、购物车库存校验、下单、支付、取消订单、退货退款、优惠券退回等所有关键路径。每条用例执行时记录一个“完成标记”、一个“关键接口响应时间”、一个“日志异常数”。22条跑完大概一个半小时速度不是重点重点是在压测后确认系统没有遗留副作用——比如压测产生的大量脏订单是否被清理、缓存是否恢复正常、异步任务队列是否消费完毕。这里有一个实操心得走查开始前先让DBA执行一次测试库的基线数据恢复脚本确保库存、优惠券余额、用户资产都回到预置状态。如果不做这一步第二次走查时可能遇到“商品库存为0”这种假性缺陷排查半天才发现是上轮走查遗留的数据。4.2 压测执行实录从1500 QPS到6000 QPS的冲击过程压测执行当天我按脚本设计了四轮加压。第一轮1500 QPS跑了10分钟系统响应时间p99在120毫秒左右CPU使用率不到30%说明系统余量还很大。第二轮3000 QPS跑了10分钟p99涨到260毫秒错误率接近零GC频率开始上升但还在合理区间。第三轮5000 QPS跑15分钟这是预估峰值p99到了450毫秒错误率出现千分之一左右的零星超时数据库连接池活跃数开始增加但是整体可控。第四轮6000 QPS我这个安排本身是故意超压找崩溃点跑到第6分钟时下单接口的响应时间突然从500ms飙到3秒错误率快速上升监控大盘上订单服务的一台节点显示 CPU 100%GC 时间占比超过40%。后来定位到根因下单接口里有一个库存预扣的同步调用数据库层面该条热数据所在的行锁竞争太激烈。6000 QPS 时大量请求同时抢同一个 SKU 的库存数据库行锁等待把线程池占满了。压测结束后我拉取了线程 dump看到大量线程阻塞在库存表的 update 语句上验证了这个判断。这个问题在5000 QPS 时没有暴露说明生产环境真实峰值下的风险只有在超压场景下才现出原形。这也是我一直坚持“冲120%甚至150%”的原因——系统在天花板附近往往藏着平时测不出来的问题。4.3 压测后的清理动作一次不能省的善后工作压测产生的脏数据必须做清理这个环节如果偷懒看似省了时间后续开发调试、测试回归甚至灰度验证都会被干扰。我的清理清单包含清空压测产生的未支付订单、恢复被扣减的库存量、删除压测账号的优惠券记录和积分流水、重置订单状态机的中间态数据、清理消息队列里的积压消息、把写入性能测试表的压测标记数据隔离并定期清理。每次压测的账号和用户数据要固定方便根据账号前缀定位和清除。有一回因为压测结束后直接下班没有清理库存数据第二天开发同学在联调环境上报“商品库存一直对不上”定位了半天才发现是压测遗留数据在干扰。从那以后我把“压测清理”写进项目结束的标准动作并把清理脚本做成自动化执行跑完压测一键触发。5. 常见问题与排查技巧实录5.1 压测环境与生产环境不一致导致的误判这是所有性能测试项目里最容易翻车的地方。测试环境的网络延迟、机器规格、数据库配置、Redis 内存等跟生产环境完全不一样。如果测试环境是4核8G的两个节点生产是16核32G的十个节点那压测数据只能作为相对参考不能直接换算成生产容量预测。我在这个项目里能做的就是“相对标尺”策略在相同环境下压测改造前后的同一接口对比响应时间提升的百分比而不是看绝对值同时在压测报告中明确标注环境差异避免业务方误读数据。5.2 压测数据不真实被缓存、被 LRU、被限流样例“保护”了压测数据不真实的问题极其隐蔽。最常见的是接口结果被 Redis 缓存命中导致压测几乎全部打到缓存上数据库压力根本没有体现。解决办法是压测时随机化请求参数同时在关键接口上绕过缓存或者直接禁用缓存层做一次“纯 DB 压力测试”。另一个隐蔽点是限流样例。某些网关或服务配置了限流规则压测流量如果被限流错误率会很高而这个错误和系统容量没有关系是限流策略在起作用。所以压测前必须先和开发确认好限流规则要么调整阈值要么在压测报告中说明。5.3 告警风暴淹没有效信息阈值红线与分级大促前告警阈值不调整真到了高峰期海量告警消息会把值班同学的注意力彻底淹没。我这次项目里专门做了一次告警规则清理删掉那些“低危且重复”的规则合并同类告警把告警通道按优先级分开——红色级别直接打运维值班电话/钉钉群置顶黄色级别只发邮件不在群里刷屏。同时为每个红色告警加了一个“建议动作”字段比如“下单失败率超过1%——先检查库存服务连接池状态再检查下单服务的GC情况最后看数据库慢查询”。告警不只是告诉你系统有问题还要告诉你怎么处理这样的告警才有意义。5.4 兼容性问题老版本客户端的腰部力量不能忽视大促测试最容易忽略的是老版本客户端兼容性。用户不会因为大促更新 App大量用户还停留在旧版本上如果服务端接口在新版本里变了协议格式老版本请求进来就会出现解析异常。我这次专门划出了一部分测试时间用线上常见的几个老版本客户端各走查了一遍主链路。果不其然发现一个兼容性缺陷新版服务端在返回优惠券列表时新增了一个字段老版本客户端解析 JSON 时对这个新字段处理不兼容导致部分老版本用户在优惠券页面白屏。这个 bug 在功能测试阶段根本不会被发现只有结合真实用户版本分布才能测出来。6. 复盘归档的价值让这次的坑变成下次的捷径测试执行完毕不代表项目结束。最后一步是复盘归档这也是我坚持最久的一个习惯。归档不是简单写个总结文档丢到 wiki 里而是要把这次项目的运行机制和判断依据完整沉淀下来。我的归档模板包含五个部分项目背景与核心目标、测试方案设计与选型理由、执行过程的关键数据、问题列表及根因分析、结论和建议。其中“问题列表”部分要区分“阻塞性问题”“非阻塞性问题”“潜在风险”三级。《测试1111》这个项目里最值得归档的是两个判断一是超压测试发现了线程阻塞的根因这个不是线上故障但如果不做超压测试这个大促期间很可能变成故障二是旧版本兼容性问题需要系统性排查这个从需求阶段就要列入测试计划而不是在测试阶段靠运气碰。归档后我会把文档转给测试组、开发组、运维组各一份。测试组据此优化测试用例库开发组拿到性能优化清单运维组更新监控阈值和预案手册。这样下一次大促来临时团队不需要从零开始而是站在上一次的基础上。如果你自己负责的项目也面临大促流量挑战我建议先不管工具、流程多么复杂先回答一个问题如果现在系统挂了能不能在3分钟内知道挂在哪如果答案是不确定那第一件事不是压测而是先做好监控和链路追踪。这个项目做完之后我个人最深的体会是测试的价值不在于发现多少 bug而在于让所有参与系统的人在发布前对它的“能力边界”有一个清晰的共识。测试报告里的每个数字都在回答一个问题系统能做什么不能做什么极限在哪里。而“测试1111”这个代号在项目结束那天也变成了团队内部资产它不再是一个随意的编号而是一套可以被反复复用的保障流程。这是我看来这个项目最值得沉淀的部分。