第 27 章 业务迭代的循环:在已有系统上叠加新需求
副题:增量——迭代 = 一次一次的增量(需求增量/代码增量/债增量);业务永不停止,系统在约束中演进;每次迭代都是全书地图走一遍
第 26 章拆完了服务:支付、内容、用户,3-4 个服务各自独立演进。业务不会停在"拆完"——新需求来了:老周说"加个二手拍卖"。不是从零开始,而是在这个已经长成的系统上叠加。本章回答:一次迭代,怎么在已有系统上走完第二遍全书地图?
读完本章,要建立三条认知——它们合起来回答一个问题:需求永远做不完,工程上怎么和它相处。
- 迭代是常态,不是例外:业务永不停止,每次迭代都是同一个演进循环的一次实例。全书的地图到这里走第二遍——第一遍是"从零建起来",第二遍是"边跑边长";
- 变化从"重来"变成"增量":新需求三分类——落在边界内的、跨边界的、打破边界的——让变化"有据可查",而不是"全员恐慌";
- 迭代有张力与停止点:节奏对质量、功能对还债,两对张力永远存在。什么时候该停下来——重构、还债、重新评估——是迭代的边界问题,也是本章的收尾。
27.1 新需求来了:二手拍卖
阶段 5 之后的一个周一,老周说:"社区里很多人问能不能卖二手,加个拍卖吧——卖家挂东西,买家出价,价高者得。"
这句话听着耳熟——全书就是从这样一句话开始的。但这一次和第一次有本质区别。第一次是在空白上:没有系统,从零建。这一次是在已有的系统上:30 万行代码、三四个服务、百万级数据、线上跑着真实用户和真实交易。所以"加功能"的每一步都在触碰已有的东西:改表要迁移,改接口要兼容,改代码要回归,上线要灰度。迭代的难度,集中在新功能与旧系统的关系上。从零开发错了可以推倒重来,没用户没数据;迭代错了要面对真实用户和真实数据——改坏了订单、上线挂了一小时、迁移丢了数据,每一样都是真账单。迭代的每一步,都是在刀尖上做增量。前 26 章建的所有体系——测试、流水线、灰度、监控——在这里全部派上用场:迭代不是重新开始,是用全部体系再走一遍。
老规矩,先开清单,把老周的话放进三分类。新增功能需求:拍卖——出价、截止、成交,卖家挂拍卖品,买家出价,时间到价高者得。影响的非功能需求:交易不能出错——这句话在拍卖里有个具体的敏感点,截止时间。最后一秒的出价和截止判定,不能乱。约束:确认一遍——技术栈、团队、合规,原样适用。为什么要专门确认约束?因为约束悄悄变化是事故之源:"数据不能丢"悄悄变成"尽量别丢",交易那章的所有防线就白建了。确认方式也简单:列出来,问一遍。而约束一旦真要修订,比新需求更敏感——改约束等于改承诺,要走评审轨道。三分类的意义,还是那句老话:把变化从"重来"变成"增量"。没有清单的团队,一次变化全员恐慌;有清单的团队,一次变化是有据可查的增量——你知道这次要动哪些验收标准、哪些设计、哪些代码,这就是变更的代价清单。
非功能需求还要再往下拆一层,拆成可测的验收线。并发正确:最后一秒出价——用压测验证,一千个并发出价加截止,成交者唯一。性能:出价接口 P95 小于 500 毫秒,预算风格的老写法。安全:出价要登录;不能越权改别人的拍卖——认证、授权、限流三条老规矩各就各位,限流尤其要上,拍卖是攻击目标,恶意抬价是标准打法。看出来了吗:非功能的验收,不是新东西,是前面所有章节的检查清单在拍卖场景里的复用——"老规矩清单"四个字,就是迭代里"非功能"三个字的全部内容。
范围也要砍。老周的完整想象里还有:出价提醒、流拍重挂、信用分。第一版砍掉出价提醒——通知链路是现成的,但拍卖提醒是锦上添花,砍需求的标准不变:不做它,不影响核心闭环。信用分也不做,和当年砍掉"先不做搜索"是同一个逻辑:复杂度没到。第一版拍卖就是四件事:挂拍卖品、出价、截止成交、订单流转。订单那章的链路现成——拍卖落在交易域,是拆服务那天就定好的位置。
范围定了,怎么记账?用版本。迭代的产物是版本,版本号是业务的刻度:每圈迭代一个版本号,功能清单跟着版本走。业务方问"2.3 版本有拍卖吗",需求清单回答。发布单按版本开,回滚按版本指,复盘按版本做。迭代靠版本记账,版本靠迭代产生——一对互相定义的概念。
团队侧的沟通也要有据可依。老周说"加个拍卖",工程师要说"这圈排不排得进"——这个对话靠什么撑住?需求清单给出影响评估,"这圈能做什么"有了依据;版本号给出承诺,"2.4 版本做"是个确定答案;优先级处理冲突,出价提醒排下圈。迭代的沟通工具就三样:清单、版本、优先级。不是"尽量快"的模糊承诺——"什么时候好"永远有答案,这个答案是版本号。业务方信任工程师,基础就在这。
最后两笔,把本章的位置钉进全书。一笔给成长:1 到 3 年的工程师,每天做得最多的事就是迭代,但多数人的迭代是"按需求改代码"——只做开发那一段;走循环的人不一样,需求翻译、决策、测试、发布、监控全程参与。同样两周,前者积累改代码的手感,后者积累一套完整方法论。本章的全部意义,就是把"做迭代"升级成"走循环"。另一笔给地图:第一章说过,每一章的对应表都试着替你的项目填一遍,填不上的那行就是认知缺口。本章就是填表的示范——拿拍卖需求,替前面每一章填一行:分类、决策、表、接口、测试、发布、监控。读完这本书的检验,说到底就是一句话:能不能用书里的地图,替自己的项目做一次迭代。
27.2 迭代循环是什么
先把迭代的定义立住。迭代,就是一次"需求、决策、设计、开发、测试、发布、监控"的完整循环——前面所有章节的动作,压缩成一圈。本书的前半本,其实就是第一圈:从零到上线,走了二十多章。从本章开始,每一圈都走一遍,但快得多——经验在、体系在、代码在:框架让迭代更快,而交付和运行的全套体系,让八段的每一环都有现成的工具。这是第二遍比第一遍快的根本原因。
八段环对着全书看,每一环都有出处。需求,分类与翻译;技术决策,九步走一遍;设计,表和接口;开发,前端后端各归其层;测试,金字塔;发布,流水线加灰度;监控,指标加告警;然后回到需求,下一轮。八段不是八周,是八种工作——拍卖那一圈,两周转完:第一周,三分类半天,决策半天,设计表和接口一天,开发五天;第二周,测试两天,发布半天,监控从发布那一刻起持续。需求翻译和决策可以压缩到一天,因为方法早内化了;监控不算时长,因为它是常态。八段的时长配比,是迭代的经验值,走几圈就有了。
节奏要固定。阶段 5 的答案是两周一圈——当年交易功能开发也要两周,如今两周一圈成了常态节奏,体系越成熟,一圈越稳。固定节奏有三个好处:可预测,业务方知道什么时候能用上新功能,发布周期说了算;可休息,团队知道什么时候发版,冲刺不是常态;可复盘,每圈结束有一个固定的时点,开三十分钟——哪环慢了,哪环出错了,下圈改什么。复盘进迭代,是排障复盘的功能版,同一件事在两个尺度上各做一次。
现在说这一章最重要的一个关系:迭代循环和演进循环,是大循环和小循环。演进循环管宏观——业务复杂度上升,原方案无法承受,换方案,那是架构级的动作,比如拆服务。迭代循环管微观——需求进来,功能出去,一圈一圈转。两个循环的接口在复盘那一问:这圈跑完,业务复杂了吗?原方案还承受得住吗?承受不住的信号出现时——协作撞车、数据告急——触发大循环。小循环一圈圈积累业务增长,大循环处理小循环攒下的结构性变化;拆服务那一章,就是好几轮小循环攒出来的结果。本章的位置,就在两个循环的交点上。
演进条件的检查,也借这个接口落地。决策记录的每一行都写着演进条件:缓存是首页变慢,凭证方案是多服务,编排是几十容器。迭代时顺带检查一遍:触发了吗?触发了,就重评估当年的决策。这是迭代的体检项目——功能迭代做功能体检,演进条件做架构体检,每圈一次,不会忘。演进条件写在决策记录里,就缺一个固定的检查位置,迭代节奏正好是它该待的地方。
迭代的"严与松",跟着团队走。1 人团队,一圈就是想到就做;8 人团队,一圈要有评审和流水线;30 人团队,一圈是评审、灰度、监控、复盘的全套。流程、架构、迭代,同一个函数——都是团队规模和业务复杂度的函数。这是"流程是团队的函数"走到今天的收官形态。
迭代还有两种节奏要搭配。一种是功能迭代,本章的主线。另一种是还债迭代——当年技术债那章说过,要定期专门还债,这里给它排位置。建议的节奏:三圈功能,加一圈还债。债不还,迭代会越来越慢;与其等债积累到无法承受再被动还,不如主动排期。还债那圈做什么?重构烂代码、补测试、补文档、升级依赖——没有新功能,但下一轮功能迭代会快三成。这是还债的收益账,也是"还债迭代"这四个字值得占一圈的理由。
放到全书地图上,本章是走第二遍的收官。第一章的地图有三条线,业务线、技术线、工程线。第一次走地图,是学:设计、请求走通、快对稳防久、交付运行、架构演进。第二次走地图,是本章:新需求进来,三分类开业务线的入口,决策用方法论,设计走技术线,测试发布监控走工程线——三条线在一圈里全部经过,八段环就是地图的操作流程版。地图不是知识清单,是操作流程——这句话到这里有了完整的演示。读完本书的检验标准也由此落地:遇到新需求,能不能在脑子里自己把八段环走一遍。本章,就是这份检验的模拟卷。
27.3 需求:第二次翻译
迭代的第一段,是需求分析。业务语言翻译成技术语言——这个动作前面做过一次,这次再来,只是要翻译的东西多了:新增功能、非功能影响、约束确认,三样一起翻。
先开三分类。新增功能需求,翻成四件事的功能清单:挂拍——卖家发布拍卖品,起拍价、截止时间、加价幅度;出价——必须高于当前价加幅度,最后一分钟是敏感区;成交——时间到,最高价者得,最后一秒的出价与截止判定谁先谁后,是并发点;订单流转——成交后走订单链路,支付、发货、确认,全部复用现成的。影响的非功能需求,翻成验收标准:"交易不能出错"在拍卖场景里具体化成一句话——截止时间到,正好有人出价,结果必须确定且唯一。这一条能写出来,开发就可以开始。约束,确认一遍不变:技术栈、数据不能丢、安全基线——确认这一步不能省,迭代中悄悄放宽约束是事故之源,约束是承诺。
这次翻译有一个新动作:影响评估。第一次翻译时没有旧系统,这次有了——每个需求都要问一句:它碰到哪些已有的东西?碰表吗——重审建模;碰接口吗——考虑兼容;碰流程吗——想想协作;碰数据吗——要不要迁移。问完,产出一张触碰清单:挂拍卖,碰商品表吗?不碰——建新表 auction。出价,碰用户认证、碰限流、碰并发。成交,碰订单链路、碰支付、碰对账,全是复用。这张清单就是开发计划——按触碰点排开发顺序,排障时的思路在这里变成开发时的排程。
拍卖这个业务,有两个机制要专门立。第一个是状态机。拍卖品有生命周期:待开始、进行中、已结束、成交或流拍。状态转移表写清楚:谁能从待开始到进行中?开始时间到。进行中到已结束?截止时间到。非法转移一律拦住——已结束之后不能再出价。为什么新功能也配状态机?因为拍卖和订单一样,是时间敏感加并发的业务,出价乱序就是成交错误。状态机不是交易的专属,是一切有状态业务的通用武器。
第二个是截止时间的并发设计。"时间到"和"出价"的先后,是纯粹的并发问题,实现要点一条:截止判定用数据库事务加状态检查——出价时检查拍卖品状态仍是进行中;截止时把状态改为已结束。已结束之后来的出价,被状态机拦在门外。交易的防线——状态机、事务、幂等——在拍卖里一套不少,原样照搬。这就是"新功能的老规矩"的准确含义:老规矩不是比喻,是清单。
验收标准要落到能测。写出的标准,检验方式只有一个:能不能写成测试用例?拍卖的三条:出价成功条件——金额和时间判断,能写成单元测试;成交唯一——并发压测的断言,能写成压测脚本;订单流转——端到端测试现成。三条全过检验。标准进了测试用例,才叫可用——这是"第一批验收标准可用"在迭代里的检验方式。还值得一提的是,验收清单本身是活的:需求会变、用户会反馈、债会还,清单永远在更新——第一次开发前它是约定,这一次它兼做开发后的检验,同一个清单,两种用法。
最后,分析瘫痪的防线原样有效。拍卖的规则能讨论一个月:悔拍怎么办、出价能不能撤销、异常出价怎么算……防线还是那条:写出第一批验收标准就开工。拍卖第一版的三条已经够用——出价高于当前价且时间未到则成功;截止后最高价者成交且唯一;成交后订单进入现成的订单流程。三条够开发了,剩下的交给下一圈迭代。
27.4 决策与设计:复用还是新建
迭代的第二、三段,是技术决策加设计。先说决策的性质:这一次的决策比第一次小,但一样要走九步。决策模型走到今天已经用得很轻了——选技术栈那次是完整走,拆服务那次也是完整走,这次只有三四个候选、三四个维度。模型不是每次都全量,是每次都有框架:小决策小走,大决策大走。轻量不是偷工,是内化。
决策模型。① 目标:拍卖功能上线,不动摇已有系统。② 约束:三四个服务、订单链路现成、迭代周期两周。③ 问题:拍卖的代码放哪?④ 候选:A,独立拍卖服务,新服务加新库;B,并入交易域,复用订单和支付服务,新增拍卖模块和拍卖表。⑤ 维度:边界匹配——拍卖属于交易域,拆服务那章就定过;复用收益——订单、支付、对账全部现成;独立成本——新服务意味着部署、监控、链路各多一份。⑥ 打分:A 的独立在"拍卖只是交易的一种形态"面前过度——拍卖的成交就是订单,拆出去等于订单链路跨服务,分布式复杂度的学费白付。B 的复用顺理成章:拍卖表进订单域,建模的规矩在这里再过一遍——拍卖品有独立的生命周期,起拍、出价、截止,所以建新表,不碰商品表。⑦ 选择:B,复用交易域,新增拍卖和出价两张表加一个模块。⑧ 收益:订单、支付、对账、风控全部复用,防线原样生效;部署、监控、链路不新增。⑨ 代价与演进:交易服务会变大,拍卖逻辑挤进来。演进条件记下:拍卖业务量接近交易主业务时,再拆独立服务——拆的优先级公式还是那个,变更频率乘以独立性,拍卖还小,先不拆。
这行决策照例写进记录,将来被质疑时有答案——"为什么拍卖不拆独立服务?"——记录里写着演进条件。这张表越填越长:语言、数据库、前端框架、认证、缓存、工作流、可用性目标、拆服务、消息队列,再到今天的拍卖方案。每一行都是业务逼出技术的坐标。而迭代时代,这张表有了新用法:每圈都可能添新行,小决策也记——"出价提醒用现有通知链"也是一行。决策记录的完整生命周期到此走全:写下,执行,被演进条件触发,重评估,更新。记录是活的。
设计段的策略,一句话:改动最小化。迭代设计的评判标准不是最优,是改动最小——能加表不加字段,能加字段不改表,能新接口不改接口,三级递减。为什么"最小"优先?改动越小,回归面越小,回滚越容易,影响评估越简单。正确姿势是在够用和留余地之间,找那个最小的改动。
表和接口的实景,照这个策略走。表:现有表接得住吗?接不住——商品表装不下拍卖的独立生命周期,建新表。auction 表:起拍价、截止时间、状态;bid 表:金额、时间、用户。新表不碰旧表,这是改表贵的账最便宜的一种结法:加表不是改表。状态字段先留足:待开始、进行中、已结束——状态机的风格,建模纪律再次生效:够用且留有余地。接口:三个新接口,发布拍卖、出价、查拍卖,版本化规矩照旧,v1 起步。出价要带幂等键——连点出价等于重复出价,交易那章的防线原样照搬。已有接口这边也有纪律:拍卖要调订单接口,给已有接口加参数,只加不改不删,加可选参数安全,改语义危险;改动走 v2。动手改之前,先查依赖清单——谁还在用这个接口,查完再动。
最后把这次决策放进全书的决策层级里收个尾。拆服务是大决策,定框架;复用交易域是小决策,在框架内填空。大决策定方向,小决策填细节,演进条件串起两层——决策不是一次性的,是分层的。这也是决策模型的收官形态:从一个人选技术栈,到三十个人拆服务,再到每一圈迭代添一行记录——九步没有变过,变的是走它的人和它记录下的世界。
27.5 开发与测试:在已有系统上改
迭代的第四、五段,是开发加测试。先说这段的性质:在已有系统上开发,和从零开发完全不同。
开发的节奏,体系早就铺好了:功能分支、本地自测、PR、测试环境自动部署、联调验收——每一步都有现成工具,开发段的快是体系给的,不是手速。迭代的另一个快来自并行:验收标准定了,测试用例就能先写,不等开发完;开发完一个模块,测一个模块。需求、设计、测试并行准备,开发、测试交错推进——而并行的底气是自动化:每次合入,流水线自动跑测试。
开发的第一策略,一句话:能加就不改。新功能用"加"——新模块、新表、新接口;旧逻辑少"改"。为什么?加的风险是新增代码的 bug,可控,测试覆盖新代码就行;改的风险是破坏已有行为,不可控,要全量回归。声明式框架在这里兑现它的承诺:加拍卖,就是加状态加界面描述,加功能从全链路排查变成局部修改——框架的收益,到迭代时代才完全显现,现在就是显现的时候。后端同理:拍卖落交易域但模块独立,新增代码不影响已有行为的概率,远大于改动代码。
说到复用,开发第一周的样子是这样的:读订单代码,写拍卖代码。成交要调订单接口,调用方就得读懂别人的机制——状态机、事务怎么写的,然后遵守别人的约定——幂等键带上,错误码认账。"复用"的代码含义,就是读懂别人的机制、遵守别人的约定。而读懂靠什么?知识传没传到位。决策记录里写着为什么这么设计,提交信息和 PR 描述写着这次改了什么,注释写着这段为什么这么写。知识在,迭代就能改;知识不在,迭代靠猜——新人能不能独立做满一圈,取决于知识传没传到位。迭代也是对团队知识库的一次检验。
测试段,先立拍卖的特殊性:普通功能的用例是"输入到输出",拍卖多了时间维度。三条用例必须单独立:截止竞态——出价和截止同时发生,结果必须确定,测试断言"要么出价成功要么被拒,没有第三种";重复出价——连点两次,幂等键拦下;越权——A 不能出 B 的拍卖,授权的规矩照常。拍卖的测试清单,就是状态机转移表加并发用例加授权用例——前面章节的测试思路,在新场景里重排一遍。
然后是全节的命门:回归。迭代最怕的不是新功能有 bug,是旧功能被改坏。而全量回归要两天——这个数字是阶段 5 的真实成本。金字塔在这里兑现价值:单元测试盯出价逻辑,高于当前价、截止判定——并发判定是单元测试的黄金用例,最后一秒的先后,代码里就是一个锁一个状态判断;集成测试盯接口,幂等出价;端到端只跑核心路径——挂拍、出价、成交、订单。承诺没变的地方,不用全验。回归从两天降到两个小时。所以"迭代快"的真相不是写得快,是回归快。
测试全绿之后,链条自动接上:流水线构建、部署测试环境,发布单、灰度、监控。迭代的测试不是终点,是流水线的入口——测试、流水线、发布、监控,在迭代里是一条链,前面五章建的体系原样运转。
联调比第一次轻得多。前后端联调,契约的规矩照旧:字段、错误码、请求 ID;出问题了,三问照旧:断在哪一段、卡在哪一层、数据卡在哪个环节。服务间也一样:拍卖调订单的接口,契约测试兜底。第一次联调是建工具,以后的联调用工具——这句话在迭代时代成了字面事实。
最后一个小动作:路过就还。开发走轨道,PR、评审、提交信息,一个不少;走到订单模块的时候,顺手整理旁边的烂代码——债在迭代里还,比专门还便宜。定期还债迭代是集中还,路过就还是零星还,两条腿走路。
27.6 发布与监控:迭代的验收
迭代的第六、七段,是发布加监控。先立这段的性质:上线不是迭代的终点,是验证的开始——部署完成,是运行期的起点。
发布的准备工作,是一张发布单。每圈迭代一张,四个栏目:新功能清单,这圈发了什么;回滚方案,拍卖出了问题怎么回——切流量加关入口;监控关注项,这圈上线重点盯哪些指标;值班确认,值班的人知道这圈要发什么。发布单本质是交接文档,开发和值班之间的信息桥——知识传递的老规矩,换了个载体。
发布走灰度。拍卖涉及钱,是高风险发布,金丝雀是标配:先放 1% 的用户能挂拍,观察指标,逐步放量。回滚路径提前备好:指回制品,发布单里写明的动作。而整条发布链上,人只做两个动作——确认发布单、点灰度按钮,其余全交给流水线:合入、构建、测试、部署测试环境,全自动。半自动交付的决策,在迭代时代是每圈的日常形态。
发布日是团队的仪式,不是一个人的动作。固定在每圈末尾的同一时间——比如周五下午低峰。固定时间窗有三个好处:可预期,业务方知道周五有新功能;可准备,值班的人知道周五要盯;可回退,发完有问题,周一之前都从容。三个好处合起来就是那句话说过的转变:发布从事件变成节奏的一部分——当年发布日求神拜佛,现在是确认、观察、庆祝,从怕变成节奏。
上线后的第一天,三看照旧:错误日志,联调没覆盖的路径有没有报错;接口延迟,出价的 P95 在不在预算内;用户行为,有没有人真的在用——挂拍数、出价数。监控体系已经把这三看自动化了大半,剩下的习惯每圈照走。
验收靠什么?靠数据,不靠感觉。功能指标:挂拍数、出价数、成交数,业务指标先看。技术指标:出价接口的错误率和延迟,预算风格的老写法——500 毫秒的出价预算。告警:出价接口错误率过 1% 就响,核心链路的规矩。老周说"拍卖好像还行",你回他数据:挂拍五百件,成交率四成,出价接口 P95 三百毫秒。"功能好不好"从形容词变成数字——当年"可测量"的验收标准,在迭代里兑现成监控指标。验收会议也因此有了内容:每圈末,老周看功能好不好用,工程师看数据达不达标,一起决定转正、回滚还是下圈改。测试是关卡,发布单是关卡,验收会议是业务关卡——三道关卡,迭代的三道闸。
还有一层保险叫功能开关。拍卖上线时开关备着:出问题,先关开关——不是回滚整个服务,是关掉拍卖这一个功能——修复,再开。灰度管流量,开关管功能,两层保险各守一段。
迭代本身也要被度量,三本账:圈均缺陷数,质量账;圈均还债量,债账;圈均时间,需求到上线多少天,速度账。三个数不为考核,只为"哪环慢了"看得见——每圈末的复盘,数据从这里来。度量不是为了数字,是为了下一圈知道改哪里。
最后是循环的闭合。监控发现的异常,反馈进下一圈当修复需求;用户提的新需求——"拍卖能不能加个提醒",第一版砍掉的那个——进需求清单,清单永远在更新。上一圈的输出——监控数据、用户反馈、债——是下一圈的输入。环在这里闭合。
老周的角色,最后交代一句。他是验收人,但迭代里他的验收升级了:功能对不对,交给测试和监控;他验的是业务对不对路——规则合不合理、体验顺不顺、商业上成不成立。人和系统的分工就此分明:系统验"做得对不对",老周验"做得对不对路"。
27.7 迭代的张力与停止点
迭代不是无限加速的永动机——它有张力,也有停止点。本节讲这两条边界。
先立底线。迭代再快,三条红线不松:核心链路的测试必须绿;涉及钱和数据的改动必须评审;发布单必须齐。三条红线是迭代的刹车——没有刹车的迭代不是快,是失控。事故的教训早就给过:快不是目的,稳才是。
张力第一条,节奏对质量。迭代越快,每圈留给测试、还债、文档的时间越少;快迭代加零还债,等于债滚债,每次"下次再还"都是利息。管理的办法有两个:节奏固定,两周一圈——节奏稳定比节奏快重要,团队知道什么时候发版、什么时候验收、什么时候休息;质量线不松,就是刚才那三条红线——轨道是底线,不是装饰。所以"快"的正确含义是稳定地快,不是冲刺地快——冲刺的账单,下一圈来还。
迭代自己也要被看见。系统有体检——演练、容量、告警;开发过程也有体检——每圈的圈均缺陷数、还债量、时间。两个体检一个目的:在变慢变坏之前看见。出事之前有信号,系统的信号是监控,开发过程的信号就是这几个圈均数。迭代也要可观测——观测的思想从系统搬到流程,一个字不用改。
流程本身还要迭代。每圈复盘除了"这圈做得怎么样",还多一问:迭代流程本身要不要改——八段环的哪段太慢,哪段总出错?这叫元迭代。成熟团队的标志,就是迭代的流程持续被迭代——流程跟着事故和复盘长,和老规矩一致。
现在讲停止点。什么时候该停下来?给一张信号清单,四个信号,全是可观察的,不靠感觉。改不动了:加一个小功能要动五处代码——分层被腐蚀了,该重构。提心吊胆了:每次改代码都怕碰坏——测试覆盖不足,债该还了。演进条件触发了:拍卖做大,交易服务变胖,当年记下的条件兑现了——该重新评估架构。事故变多了:同一类事故重复出现——该系统性修复,不是再修一次。信号到,停下——停止点也有信号,和拆服务那章的三条信号线同款:感觉会骗人,清单不会。
三个停止点,各对应一类信号,且先小后大。代码层面的停:重构。行为不变结构变,测试兜底让重构敢做——重构是迭代的投资:它让下一轮更快。债层面的停:还债迭代。这圈的产出不是功能,是改动的信心——技术债的账本上,还债等于病历清零。结构层面的停:架构再评估。重构还债都解决不了,还了债还是慢——那是结构问题,回到拆服务那章的大循环,信号三问重新过一遍。分级原则一条:能重构解决的,不用拆服务。能承受就停,到了才动——这条原则在代码尺度和架构尺度上是同一个。
停下来怎么跟业务说?业务方会问:怎么没新功能了?把"停下"翻译成业务语言:这圈修地基,下圈功能快三成。技术债要会业务化——债就是未来功能的速度。工程师的必修课由此补全:翻译是双向的,业务翻译成技术,是需求分析;技术翻译成业务,是这一课。
最后回答一个问题:系统什么时候做完?做完不存在。业务在变——新需求永远有;技术在变——演进条件等着触发;用户在变——反馈永远在路上。"完成"是一个阶段的错觉。学校教你做完一个项目,职业教你维护一个永远在长的系统——接受没有终点,是职业化的第一课。
收个尾。系统在迭代中成长,也在迭代中老化:成长靠增量,是本篇八段环教的事;老化靠还债和再评估,是停止点教的事。一边长一边修,循环不止——这就是迭代,也是这本书最后想留下的那句话:接受变化不是妥协,是工程师的日常能力。
27.8 本章对应表
| 业务诉求 | 技术选择 | 为什么 | 代价/取舍 |
|---|---|---|---|
| 新需求(二手拍卖)来了 | 三分类(第 4 章兑现) | 变化从"重来"变"增量";变更的代价清单 | 变更管理成本 |
| 迭代怎么转起来 | 八段循环(图 27-1) | 每次迭代=演进循环实例;演进条件检查在圈内(第 5 章) | 节奏 vs 质量张力 |
| 拍卖代码放哪 | 复用交易域(九步轻量版) | 拍卖落交易域(第 26 章边界);订单/支付/对账现成 | 交易服务变胖(演进条件) |
| 表接得住吗 | 表结构重审(第 6 章) | 改表贵,能不改就不改;新表不碰旧表 | 新表+迁移(如有) |
| 回归 2 天跑不起 | 测试金字塔(第 18 章) | 承诺没变的部分不用全验 | 测试维护成本 |
| 上线怎么验收 | 灰度 + 功能指标(第 23/25 章) | 上线=验证开始;业务指标先变 | 指标要定(转化率/错误率) |
| 什么时候停下 | 重构/还债/再评估 | 债是前奏不是失败(第 20 章);演进条件触发即停 | 迭代节奏放缓 |
第 27 章在地图上的位置
本章小结
- 迭代是常态:业务永不停止,每次迭代都是全书地图走一遍;
- 变化从"重来"变"增量":三分类+影响评估=变更的代价清单;
- 新功能的老规矩:接口版本化、幂等、测试承诺、轨道——迭代不发明新规矩;
- 迭代有停止点:重构/还债/再评估——小循环发现问题,大循环解决问题;
- "快"的正确含义:稳定地快,不是冲刺地快。
下一章
迭代循环转起来了:新需求进来、功能上线、监控验证、下一轮……但你发现一个更根本的问题——这些技能是怎么长出来的?你从"会写接口"到"会做架构决策",中间发生了什么?——本书的最后一个问题。
第 28 章,成长路径:1-3 年工程师如何把全书的知识变成你自己的成长路线图。