8.5 压力测试脚本的编写与执行

📅 2026/8/5 8:06:49
8.5 压力测试脚本的编写与执行
2019年一个在网易游戏做引擎开发的工程师在他的季度架构评审日上做了一件让妻子觉得“你是不是有焦虑症”的事情。他把家里所有资产和负债列在一张Excel表上然后开始手动输入各种极端数字——房价跌百分之四十、沪深300再跌百分之三十、他被裁且十二个月找不到同级别工作、他妻子所在的外企突然退出中国市场。他妻子路过书房的时候瞥了一眼屏幕问他是不是在写灾难小说。他说不是是在做系统压测。2022年他所在的游戏部门因为版号停发和政策调整被迫裁员他妻子所在的外企确实开始收缩中国区的业务线。他们家在同一季度里失去了一份半的主动收入。他后来跟我说他在那个季度里唯一没有焦虑的事情就是他早在三年前就已经算过知道最坏情况下他们家能撑二十三个月。他说当人力部门把离职协议推到他面前的时候他脑子里想的不是“我完蛋了”而是“这个数字和我三年前那版脚本里假设的离职补偿金额只差了五千块”。他签完字回家打开那版压力测试脚本把实际数字更新进去然后给妻子发了一条消息和预期一致按预案执行。脚本结构设计输入变量、计算逻辑、输出结果缺一不可你写过的任何一个像样的测试脚本都有三层结构定义输入执行逻辑校验输出。压力测试脚本也不例外但它的特殊之处在于输入变量不是你平时测试策略时用的历史收益率序列而是你家庭资产负债表上每一项资产和负债在极端条件下的模拟价值。计算逻辑不是在回测你的择时胜率而是在模拟你的现金流在多重极端冲击下从正常运转到彻底断裂的完整时间线。输入变量层是你需要自己定义的最关键部分。你不能只测一个“股市跌百分之三十”的单变量场景因为真实世界的极端事件从来不是单变量冲击。2008年是股市暴跌叠加失业率飙升2020年是公共卫生危机叠加全球供应链断裂2022年是中概股崩塌叠加互联网行业大裁员。每一次真正的危机都是多个变量同时向你最脆弱的方向冲击而你的压力测试脚本必须模拟这种多变量并发的场景。你至少需要设定以下五类输入变量金融资产跌幅包括你的股票仓位、指数基金、行业ETF、以及任何和股票市场挂钩的理财产品在压力场景下你给它们分别设定跌幅假设个股跌幅应该远大于指数跌幅而且要注意一个你在平时不会注意到但在崩盘时必定出现的现象——所有资产之间的相关性在极端尾部会迅速趋向于一你以为分散在不同行业、不同市值风格、不同地域的持仓能互相对冲但在真正的系统性危机中它们会一起跌你的分散化只能保护你在温和回撤时的体验保护不了你在踩踏时刻的绝对净值不动产跌幅自住房和投资性房产各自设定一个你认为在本轮周期内可能出现的最大回调幅度同时还要考虑如果房贷利率跟随基准利率飙升你的月供利息部分会发生什么变化人力资本冲击也就是你和你家庭其他主要劳动力的主动收入可能遭受的损失幅度和持续时长失业、降薪、被动转为兼职或自由职业但实际收入大幅下降这些情况都要被量化成具体的月收入数字和恢复周期假设通胀和生活成本在真正的极端场景里物价可能出现你不熟悉的涨幅CPI的温和波动和你家真实感受到的生活成本上涨往往不是同一个数字你需要给你家庭的月度硬性支出设定一个压力情景下的增长率以及负债利率如果你持有浮动利率的负债——无论是挂钩LPR的房贷还是其他浮动利率的借款——你必须假设一个利率飙升的场景。计算逻辑层要完成的事情是把这些输入变量按照真实的因果关系串联起来计算出一条你家庭净现金流随时间变化的曲线。你的月度现金流入包括主动收入、被动收入股息债息租金以及你已经锁定的离职补偿或失业保险金。你的月度现金流出包括全部硬性支出——房贷或房租、生活基础消费、保险续费、子女教育、以及压力情景下可能新增的医疗支出或应急支出。净现金流入减去净现金流出就是你家每个月的资金池增量。当增量持续为负时你的应急储备金开始被消耗。应急储备金归零的那一天就是你系统的崩溃点。在归零之前你需要标注出几个关键节点你被迫开始赎回固收类资产来补充流动性的时刻固收类资产耗尽、你被迫开始卖出权益类资产不管那时股价跌了多少的时刻以及你被迫开始出售非流动性资产车、投资性房产、甚至自住房的时刻。每一个节点的触发时间都是你系统设计质量的最诚实评分。输出校验层是整个压力测试脚本里最让你难受但也最重要的部分。你不能输出一个模糊的感受——“我感觉我们家应该扛得住”。你必须输出一个精确到月份的崩溃时间。你在所有触发条件下家庭现金流断流的最早时刻是哪个月那个时刻你还有多少未变现的资产但无法及时转成现金你被迫割肉的那个月你的权益类资产市值比你买入成本跌掉了百分之多少如果这些问题的答案超出了你能承受的底线那你的系统架构必须在压力测试之后被送回第二章的架构评审会重新调整内核层厚度、系统服务层比例和应用层沙箱配额然后重新跑一次压测直到崩溃时间落在你能接受的底线之后。用Excel就够真正的挑战不是计算是诚实读完上面那段你可能会觉得这个脚本需要搭一个Python环境跑蒙特卡洛模拟做几千次随机采样才能算出结果。不需要。你的家庭资产负债表上的条目数量大概率用不了一张A4纸的正反两面。你的资产类别——现金、固收、权益、不动产——四个大项每个大项下面小项加在一起可能只有十几二十行。Excel完全够用而且是比任何编程语言都更适合做这件事的工具。因为在Excel里你每一个单元格的公式都可以被你妻子、你父母、或者任何一个不写代码但需要参与你家庭财务讨论的人点开看看你的计算逻辑是不是合理看你的假设是不是过于乐观。透明本身就是一种纪律。压测脚本真正的难度从来不在计算上。你有能力手写一个分布式一致性协议你的计算能力远超这份脚本需要的全部数学。压测脚本真正的难度在你输入那些假设数字的那一刻。你敢不敢在“失业后重新找到同级别工作的恢复周期”那一栏里写十二个月你敢不敢在“自住房产最大回撤”那一栏里写百分之三十你敢不敢把这两个数字放在同一张表里然后让公式算出来的结果显示给你和你配偶看——你们家在第十一个月之前就会耗尽全部流动资产大多数人不写压测脚本不是因为不会写是因为不敢看输出结果。你写代码的时候从来不回避压测——你主动把QPS拉到集群极限你主动往数据库里插入脏数据你主动拔掉一台核心服务器的网线然后看监控面板。你做这些事的时候心态不是恐惧是专注。因为你清楚你现在主动制造故障是为了将来被真实故障突袭的时候你不需要在恐惧中临时做判断。把你对待线上服务的工程师心态用在对待你家庭财务的压测脚本上。找一个周末下午关掉手机泡一杯茶打开Excel诚实地输入那些你一直在回避的假设数字。让公式跑出结果盯着那个崩溃月份的数字看几分钟。如果太短不要恐慌——你还有时间。回到前面的章节去加固你的内核层调整你的资产配置增加你的保险覆盖延长你的应急储备金水位。然后下个季度重新跑一次。直到崩溃月份变成一个你即使在最坏情况下也能坦然面对的数字。定期回归测试重大变更之后必须重跑全量你在CI流水线里配置自动化测试的时候一定加了一条规则每次提交代码全量单元测试必须重新跑一遍。不是因为你每次改的代码都会把原有功能搞坏是因为你不知道哪次修改会把原有功能搞坏。而在你不知道的时候让机器替你跑一遍所有测试比你上线之后用户替你发现Bug便宜得多。你的家庭压力测试脚本就是你家庭财务系统的全量回归测试套件。触发回归测试的条件不是时间——不是你设定一个日历提醒每年跑一次。触发回归测试的条件是资产量级跃迁和人生阶段切换。你的资产每增加一个量级——你的总净资产从五十万跨过一百万从一百万跨过三百万——你原有的压力测试假设就不再适用了。一百万的时候你的应急储备金覆盖十二个月生活支出是一笔数字三百万的时候你的生活支出可能已经因为换房、生娃、子女教育而同步膨胀了那笔应急储备金还能覆盖十二个月吗你需要在净资产每跨过一个显著台阶的时候重新坐下来把压力测试脚本里和支出相关的所有输入变量全部更新一遍重新算出那个崩溃月份。人生阶段的每次切换也是回归测试的强制触发条件。你结婚了你的家庭财务系统从此不再是单核处理器你的配偶的收入和支出要全部纳入脚本你们两个人的主动收入同时中断的概率远低于一个人但你们两个人的生活支出也高于一个人两条新变量的引入必须被完整测试。你买房了你的负债端多了一笔长达三十年的硬实时任务月供就是你的债务时钟脚本里必须新增一列输入变量专门模拟利率变化对月供的压力。你生娃了未来十八年甚至更久的抚养和教育支出不是一次性计入而是作为一条持续增长的支出曲线叠加到你原有的月度消耗上。每一次回归测试跑完你的崩溃月份可能会变短——因为你的生活更复杂了你的责任更多了你的支出更刚性了。这不可怕。可怕的是你生活已经变了但你的压力测试脚本还停留在你单身时那个只有租房支出、没有负债、一人吃饱全家不饿的旧版本里。用旧版本的测试结果来评估新版本系统的安全性是你职业生涯里绝不会犯的低级错误。别在你自己家的事情上犯。