CHAPTER 051 / 100
第五十一章:团队磨合完成,配合进入稳定期
听这一章
微软云希 · AI 合成朗读 · 18:44
一个团队开始顺起来,最明显的信号不是群里没人说话。
是大家说的话终于不用再猜。
周三早上九点半,我们照例在小会议室过当天的联调计划。投影上开着接口文档,旁边是伟源整理的测试矩阵。小马哥把企业端页面切到测试环境,小璇的设计稿停在批次详情页,我则连着后端日志和数据库查询窗口。
换成刚组队那几天,这种阵仗至少得先花半小时确认谁手里是哪一版。
现在不用了。
“今天先走三条。”伟源翻开本子,“正常创建,超时重试,回调后立即查询。跑完再看批次里的部分失败。”
小马哥点开页面:“请求编号和企业业务单号都显示出来了,出问题直接报这两个,不再靠截图找缘分。”
我看了一眼时间。
早会开到第十二分钟,没人临时加需求,也没人说“这个应该很简单”。
光这一点,就已经有点像成熟团队了。
第一轮联调开始后,小马哥提交了一个包含六条任务的批次。接口返回批次号,数据库里落下一条批次记录和六条任务明细,额度记录也跟着创建。页面上的状态从“已提交”变成“生成中”,模型结果回来以后,又顺利切成“已完成”。
伟源没有急着说通过。
他把同一个企业业务单号又提交了一次。
接口返回的还是原批次号,数据库里没有多出第二份任务,额度也没有重复占用。
接着,他让回调地址故意慢几秒。任务结果先落库,事务提交后,回调任务才开始重试。小马哥收到回调,立刻刷新查询页,看到的已经是最新状态。
从接口到数据库,再从数据库到回调和页面,整条链路跑得很安静。
安静得我一度怀疑日志是不是没开。
小马哥盯着页面,压低声音说:“雷子,今天这几位服务是不是背着我们和好了?”
“别打扰它们。”我说,“分布式系统关系刚稳定,最怕外人多嘴。”
伟源在三个用例后面打了勾。
“主流程通过。现在跑部分失败。”
这句话一出来,我心里那点刚冒头的轻松立刻收了回去。
主流程顺,只能说明大家在正常情况下愿意讲道理。异常链路才是团队和系统真正露脾气的地方。
伟源把六条任务中的一条换成不支持的风格参数,再次提交。
前五条陆续生成成功,最后一条被模型侧拒绝。数据库里五条成功、一条失败,失败原因也正确落了下来。批次表的最终状态更新成了“部分成功”。
后端没报错,数据也对。
可页面上的批次状态还停在“生成中”。
加载图标一圈一圈地转,转得特别认真,仿佛只要它足够努力,那条失败任务就能被转回来。
小马哥先看了前端响应,又转头看我。
“你接口返回的是 PARTIAL_SUCCESS?”
“对。”
“我这边完成态只有 SUCCESS 和 FAIL。”
“上周不是说过加部分成功吗?”
“你上周说的是,前端先按明细数量判断,批次状态后面再补。”
我下意识想反驳,话到嘴边又停住了。
那句话我确实说过。
当时数据库状态还没定,为了让小马哥先把页面跑起来,我在工位旁边说了句“你先按明细判断”。后来做回调和重试时,我发现由前端自己统计会有时序问题,于是把“部分成功”补进了批次状态。
伟源的用例按后来的数据库设计更新了。
小璇的页面也已经画了“部分成功”的展示。
只有小马哥还守着我最早那句临时口径。
代码都没写错。
错的是四个人分别拿着四段都曾经正确过的信息。
会议室安静了几秒。
小马哥把鼠标往桌上一放,倒没有发火,只是看着我问:“所以我以后是信文档,还是信你站在我旁边临时发布?”
他说得有点损,但问题很实在。
以前我们熟,很多事在工位边说两句就开干。速度确实快,快到结论改了以后,旧口径还会留在某个人的代码里继续服役。平时看不出来,联调时一碰头,才发现大家接的根本不是同一个协议。
伟源合上测试本。
“现在改前端或者改接口都不难。”他说,“但今天不把状态定义定死,回归通过也只是碰巧。”
小璇把设计稿切到批次列表。
“还有用户这边。”她指着那条仍在转圈的记录,“五条已经能用了,一条失败,页面不能一直告诉他还在生成。应该直接显示‘部分成功’,把成功数量和失败数量讲清楚,再给失败项单独重试的入口。”
她停了一下,又补了一句:
“状态不是后端字段换个中文。它得告诉用户现在发生了什么,下一步能做什么。”
这句话把问题彻底钉住了。
我们缺的不是一个枚举。
是从数据库事实、接口协议到用户感知之间,一套所有人都认的翻译规则。
我看着投影上的接口文档,页面底部的更新时间还是前天晚上。文档不是没更新,业务单号、回调顺序、模型版本都写得很清楚,偏偏“部分成功”只留在数据库说明和测试用例里,状态表还停在最早那版。
这次锅不用查日志。
日志正坐在会议室最里面,姓阿。
“先暂停联调。”我说,“不补临时判断。今天把状态和变更流程一起收口。”
我们把前天更新过的接口文档重新打开,先补上版本号和变更记录,再从批次状态开始重新对。
我负责把后端事实说清楚:什么情况下算生成中,什么时候进入成功、失败和部分成功;批次状态由哪一层计算,什么时候落库;接口返回什么固定值,旧数据怎么兼容。
小璇负责把每个状态翻译成用户能看懂的页面:列表显示什么,详情页展示什么,按钮何时出现,失败原因放在哪一层,不让用户靠颜色猜系统心情。
小马哥把前端实际需要的字段、示例响应和刷新条件补上,也把刚才那句“先按明细判断”从自己的待办里划掉。
伟源坐在旁边,一边听,一边把每个结论变成测试用例。
正常成功怎么验。
全部失败怎么验。
部分成功怎么验。
回调比页面轮询晚时怎么验。
失败项重试成功后,批次状态又该怎么变化。
以前开这种会,我最容易犯的毛病是边听边给方案。谁说一句,我立刻翻译成代码;谁提一个边界,我马上想数据库该加什么字段。脑子跑得很快,看起来特别积极,实际经常把讨论带进实现细节,最后业务状态还没说清楚,大家已经开始争该用整数还是字符串。
这一次,小璇在白板上先画了四个方框。
生成中、全部成功、部分成功、全部失败。
“先别想怎么存。”她把笔递给我,“先确认用户在每个状态下能看到什么,能做什么。”
我接过笔,没有跟她争。
我们先把页面行为定下来,再往回落接口和数据库。部分成功时,成功结果立即可用,失败项保留明确原因,可以单独重试;全部失败时不显示空白结果区,直接给出失败列表;仍在生成时则展示当前完成数量,不提前开放重试。
页面规则明确以后,我再把它们映射到后端状态。小马哥根据固定枚举控制展示,不再自己从明细猜批次是否结束;伟源则要求所有终态都加一条校验:数据库状态、接口状态和页面文案必须一致。
讨论到一半,小马哥忽然问:“以后又加新状态怎么办?比如人工审核中。”
我差点顺口回一句“到时候再说”。
好在这句话刚冒头,就被今天的加载图标在我脑子里转了回去。
“先提变更卡。”我说,“写清为什么加、谁会看到、接口怎么返回、数据库有没有影响、旧版本怎么办。评审完再改。口头说过不算完成,聊天记录也不当长期文档。”
小马哥点点头:“也就是说,你在我旁边临时发布的版本,以后默认不进生产。”
“对。”
“那稳定性至少提升百分之三十。”
“你这个数据来源呢?”
“口头结论。”
会议室里笑了一阵。
这次我没觉得他在拆我的台。
一个团队能拿负责人的旧毛病开玩笑,又能在笑完以后把规则写下来,说明大家已经不需要靠客气维持协作了。
中午前,我们把前天那张变更表又收紧了一层:不只记录需求是谁提、这次做不做,还必须关联接口版本、状态定义、示例响应、数据影响、页面行为、兼容方式、负责人、评审人和验证结果。任何一项外部协议变化,都从这张卡进入;紧急问题可以先止血,但当天必须回写,普通变更评审以后再改,第二天早会只认文档里的最新结论。
它没有解决所有沟通问题。
至少以后再出问题,我们能知道是规则没定、文档没改,还是代码没跟,而不是四个人围着屏幕互相回忆上周谁在茶水间说过什么。
下午两点,第二轮联调重新开始。
这次没有人急着点按钮。
小马哥先确认页面使用的接口版本,伟源核对测试用例编号,我检查数据库脚本和服务配置,小璇则在旁边过了一遍最终文案和按钮状态。
“可以。”她说。
小马哥点击提交。
八条任务一起进入系统。
第一条成功。
第二条成功。
第三条因为模型参数不支持进入失败。
后面五条陆续返回结果。
批次状态从“生成中”切到“部分成功”,页面直接显示“成功 7 条,失败 1 条”。成功的音乐可以正常试听和下载,失败项旁边出现单独重试按钮,点开还能看到具体原因。
伟源没有说话,又把同一个业务单号提交了一次。
接口返回原批次,数据库里仍然只有八条任务。
他接着点了失败项重试,把参数换成支持的范围。新结果回来后,原来的失败明细更新为成功,批次状态也从“部分成功”变成“全部成功”。页面上的数字跟着刷新,按钮自动消失。
我盯着数据库。
小马哥盯着页面。
小璇盯着交互状态。
伟源从创建记录一路查到回调结果,最后在测试用例上打下一个勾。
“全链路通过。”他说。
会议室里停了半秒。
小马哥先抬起手:“这回能庆祝了吧?”
我还没来得及回答,他已经跟伟源击了一下掌。伟源平时最不爱搞这种仪式,愣了一下,还是抬手接住了。
小璇笑着把手伸过去。
最后三个人一起看我。
我只能把手抬起来。
四只手在会议桌上方碰到一起,声音不大,却比报警群的提示音好听多了。
那一刻真正让我高兴的,不是接口终于返回了正确状态。
是这次成功没有靠谁临时兜底。
小马哥知道自己该对哪份协议,伟源知道每个变化该怎样验证,小璇从设计阶段就把用户状态讲清楚,我只需要把系统边界和数据规则收住。每个人做的事不一样,最后却落在同一条链路上。
以前我们也一起干活。
但那更像几个熟人并排开着各自的线程,遇到问题再靠喊话同步。现在才真正有了共享的节奏:该并行时并行,该等待时等待,结果出来以后,还有人负责确认整个事务到底算不算完成。
小马哥甩了甩刚才被我拍红的手。
“雷子,你击掌怎么跟合并代码一样,非得用力确认?”
“怕你前端没收到回调。”
“收到了,建议下次改成异步。”
伟源低头继续写测试结果,嘴角却一直没压下去。
那天下午剩下的时间,办公室没有发生什么大事。
这反而是最好的事。
产品提了一个结果筛选的小调整,小马哥自己拉了变更卡,跟小璇确认页面行为,再请伟源补验证范围。三个人把影响和时间写清楚以后才来找我,我只看了接口是否需要改动,确认不影响现有数据,就让他们按流程推进。
没有人问我第一步该做什么。
也没有人做到一半才跑来告诉我,数据库可能还得顺手加一列。
我第一次在工作日下午连续两个多小时没有被联调消息切断。
那两个小时里,我把一直压在待办底部的架构图重新打开。企业端业务越来越多,模型版本也开始分叉,再让业务流程直接认识每一种模型参数,迟早会把调用链写成一团不断追加的条件判断。
我把模型能力、版本适配和任务调度重新分了层,又补上调用耗时、失败类型和版本分布的监控设计。以后模型升级,业务层只关心任务需要什么能力,不必跟着每一个参数版本一起改。
这些东西当天当然做不完。
架构优化也不是在白板上画几个方框,系统就会自动长得漂亮。可我终于有完整时间去想下一步,而不是永远被当前这一处报错追着跑。
负责人能腾出手做更远的事,不是因为他把眼前的活都甩给别人。
是团队已经能把眼前的活接稳。
傍晚六点,小璇把新一版批次页发到群里。她没有只改“部分成功”四个字,还把成功结果、失败原因和重试操作重新排了层级。用户第一眼能看到结果是否可用,第二眼才看到哪里失败,不会因为一条异常就对着整页红色提示发愣。
小马哥按设计把页面调完,伟源拿上午的四种状态又走了一遍。
没有人专门组织第三次会议。
群里只有几条很短的消息。
“已更新。”
“已验证。”
“可以合。”
我看着那三条消息,忽然觉得所谓稳定运行,大概就是这样。
不是再也没有分歧,也不是每个人都能提前知道别人想什么。是分歧出现以后,大家知道去哪儿对齐;变化发生以后,知道该留下什么;某个人忙不过来时,其他人也能沿着同一套规则把事情往前推。
系统稳定靠的从来不是不出异常。
团队也是。
下班时,小璇先收好电脑,在我桌边轻轻敲了两下。
“我去楼下等你。”她说,“你还有多久?”
我看了一眼刚保存的架构图,又看了眼时间。
“五分钟。保存、关机、走人。”
她没催,只把我手边那杯早就凉掉的水拿走,换成自己的保温杯。
“别把团队稳定,理解成你又可以加班了。”
“收到。”
“这条要不要写进流程?”
“不用,属于最高优先级的本地配置。”
她看了我一眼,嘴角弯了一下。
“那你最好别覆盖。”
说完,她转身往电梯口走。
我没有再打开项目群,也没有趁那五分钟顺手改一段代码。关掉日志窗口以后,屏幕上只剩那张刚整理好的架构图。会议室里的击掌声好像还留在耳边,轻轻一下,却把这几周那些各说各话、互相等结果、半夜补文档的混乱都推远了一点。
小马哥和伟源已经不再是被我临时拉来救火的老同事。
小璇也不只是站在项目外面提醒我休息的人。
我们终于像一个真正能长期运行的团队,各有自己的判断,也愿意遵守同一套约定。
我合上电脑,拿起手机,给已经下楼的小璇发了一条消息:
“这感觉像后台终于不报 500。”