CHAPTER 049 / 100
第四十九章:二次项目上线轻车熟路
听这一章
微软云希 · AI 合成朗读 · 16:19
第二次站在正式发布窗口前,我终于没有再拿着咖啡杯到处晃了。
不是因为我戒了。
是因为这次该准备的东西,前一天就已经摆在桌上了。
发布清单、配置核对表、回滚版本、企业账号验证名单,还有上线后要盯的几组指标,全都按顺序排好了。小马哥负责前端和业务链路,伟源盯回归用例和异常账号,我守着后端日志、任务队列和模型调用入口。谁发现问题,先丢账号和请求编号,不在群里只喊一句“好像不对”。
这套动作,大半都是第一个 C 端项目上线以后,我们从复盘文档里一条条捡回来的。
上一次上线,我恨不得同时盯五块屏幕,哪个数字动一下都觉得系统要给我表演原地去世。这一次还是紧张,但那种紧张已经有了落点。该看什么,谁来看,什么情况需要暂停,什么情况直接回滚,大家心里都有数。
人一旦知道慌了以后先做什么,慌本身就没那么吓人了。
上午九点半,我们开始做最后一轮生产检查。
企业账号登录正常。
权限和额度校验正常。
批量任务提交正常。
队列没有积压。
模型结果能正常回写。
十点整,发布开始。
我盯着部署进度一点点往前走,手指搭在鼠标上,没再像第一次那样恨不得替服务器做人工呼吸。等服务全部起来以后,我们先用内部企业账号跑了一遍,再开放给第一批正式账号。
第一笔任务进来了。
一次提交了八条。
接口很快返回批次号,任务依次从“已提交”变成“排队中”,再进入“生成中”。模型入口的并发量没有突然冲高,结果也一条条正常落了回来。
小马哥看着页面,压低声音说:“雷子,这回好像真有点轻车熟路的意思了。”
我立刻抬手制止他。
“上线期间禁止说这种高风险词汇。”
“我说的是轻车熟路,又没说稳了。”
“意思差不多,系统听见了容易骄傲。”
伟源坐在旁边,连头都没抬。
“你们两个先别跟系统聊感情,第二个账号进来了。”
会议室又安静下来。
上午那一个多小时,主链路跑得比我们预想中顺。没有重复批次,没有模型请求扎堆,也没有前端状态长时间停住。监控上的接口耗时、任务成功率和队列长度都在正常范围里,连老板过来问情况时,我都能平静地回一句:“目前正常,继续观察。”
这句话说完,我自己还有点不习惯。
以前我汇报上线情况,要么是“还在看”,要么是“这里有个问题”,语气跟医院急诊室外等结果差不多。现在终于能把“目前正常”四个字说得像个结论,不像一句祈祷。
可项目这种东西,对你最大的尊重,就是一般不会让你顺一整天。
十一点二十七分,业务群里发来一张截图。
一个早期参与试用的企业管理员登录以后,页面、额度和新建任务都正常,可历史任务列表是空的。
产品在群里问:“这个账号以前生成过十几批数据,怎么一条都没有了?”
我看到消息,第一反应是去看监控。
全绿。
列表接口返回成功,耗时不到两百毫秒,没有异常堆栈,也没有数据库报错。从系统角度看,这次请求执行得干净利落,甚至可以拿出去当优秀样本。
从用户角度看,他的数据没了。
这就是线上最会装无辜的一类问题:每一层都说自己成功,最后只有用户什么都没拿到。
我把截图放大看了一遍,让产品先发账号标识和刚才那次请求编号。小马哥去确认页面有没有传错筛选条件,伟源马上把这个账号加进异常回归名单,又找了一个同期试用账号做对照。
没过几分钟,第二个异常账号也出现了。
情况几乎一样。
新任务能提交,历史列表却是空的。
会议室里刚松下来一点的空气,又慢慢绷紧了。
我心里自嘲了一句:“上线就像发版,每天都可能被 Bug 攻击。”
关键是这次的 Bug 还挺讲礼貌。
它不报错,不超时,也不把页面弄白,只是悄悄把用户最在意的东西藏起来,然后站在一片绿色监控后面假装跟自己没关系。
我先查了那次列表请求。
登录信息正常,企业身份也正常,查询条件里带的企业标识没有错。再往下翻,SQL 执行成功,只是结果确实为零。
问题不在这次请求,而在更早的数据里。
那几个账号都是企业端正式方案确定以前就参与试用的。当时系统里的任务记录主要按创建人保存,企业归属字段还没有完全落下来。后来我们做过一轮数据迁移,新账号和大部分试用账号都补齐了企业标识,但有少量早期批次因为创建时间太早,又经过一次账号关系调整,没有命中当时的回填条件。
现在列表统一按企业标识查询,那些没有企业归属的旧记录,自然就像掉进了夹层。
数据还在。
结果也还在。
只是新系统不知道该把它们放回哪家企业的柜子里。
小马哥把受影响账号整理出来,很快确认问题只集中在早期试用阶段,没有影响上线后新建的任务。伟源则把几种账号分开测了一轮:新注册企业、早期试用管理员、后来加入的企业成员,以及既用过 C 端又参与过企业试用的账号。
最后一种最麻烦。
同一个人名下既有个人试用数据,也有企业任务。要是为了省事,直接把“企业标识为空、创建人是当前用户”的记录全部查出来,历史列表确实立刻就有数据了。
但个人数据也可能一起混进来。
那就不是修复,是把数据隔离拆了以后告诉客户:你看,现在什么都能看见。
伟源听完我的判断,只问了一句:“先确认没有串到别的企业吧?”
“先查这个。”我说。
企业端出现数据问题,第一优先级不是让页面赶紧有东西,而是确认东西有没有跑错地方。看不到很严重,看到了不该看的,严重程度就不是同一个级别了。
我们把受影响账号前后的企业关系、旧任务创建记录和迁移日志重新对了一遍。小马哥找产品确认试用名单和当时的账号归属,伟源拿着样本逐条验证可见范围,我这边按企业关系生效时间,把能明确确认归属的旧批次筛出来。
查完以后,大家才算松了一小口气。
没有跨企业串数据。
问题范围只落在几位早期试用用户的历史记录缺少企业归属,新任务不受影响,其他正式账号也没有异常。
老板在群里问要不要回滚。
如果是第一次 C 端上线碰到这种情况,我可能会先说“我再看看”,然后自己抱着日志埋头查到所有人都不知道进度。
这次我直接把结论发了出去:
“主链路正常,新任务不受影响。异常集中在早期试用账号的历史数据,已确认没有跨企业数据泄露,不建议整版回滚。我们先定向修复旧数据,再做一轮隔离回归。”
发完以后,我又补了预计处理顺序和下一次同步时间。
不是为了显得我多专业。
是因为线上出问题时,最消耗团队的往往不只是问题本身,还有所有人都不知道你查到哪一步了。技术同学在埋头翻日志,产品在等结论,领导在猜影响范围,最后每个人都用自己的想象给事故加戏。
把边界说清楚,至少能先关掉几条没必要的焦虑线程。
中午的外卖送到以后,谁都没急着吃。
小马哥把盒饭往旁边一推,继续核对账号清单。伟源拿着我们整理出来的修复数据,先在预发布环境做回填验证。我把正式环境需要处理的记录单独列出来,每一条都带上原始创建人、对应企业、关系生效时间和任务批次号。
这次没有写一条大而化之的更新语句直接扫过去。
能明确归属的,才补。
关系不清楚的,先留着人工确认。
宁可让一条旧记录晚半小时回来,也不能为了追求页面立刻好看,把不该归在一起的数据强行塞进同一个企业。
伟源跑完第一轮验证,把结果发到群里。
“历史批次数量一致,新任务正常,个人数据未带入。”
小马哥也跟着回了一句:“试用账号归属已和产品名单对完,剩下两个特殊账号还在确认,不进本轮。”
我看着他们的消息,心里那种熟悉的发紧感慢慢降了下来。
不是问题已经解决了。
是我知道每个口子都有人守着。
以前上线出异常,我最先想到的是自己该从哪一行代码下手。现在我会先判断影响范围,再把验证、沟通和修复拆开。代码当然还是要写,数据也还是要查,但负责人真正该做的,不是第一个冲进火里,而是先看清火烧到哪儿,再让每个人拿对灭火器。
下午一点四十,第一批确认归属的历史数据完成回填。
伟源重新登录异常账号,点开历史任务列表。
原来空白的页面上,一批批任务重新出现。批次数量、生成结果和创建时间都对得上,新提交的任务也还在正常往下跑。
小马哥把截图发给产品,让对方再请用户确认一次。
几分钟后,群里回了四个字:
“现在有了。”
没有掌声。
也没有谁站起来说问题圆满解决。
大家只是把已经有点凉的盒饭重新拉到面前,边吃边继续看监控。因为我们都知道,修复一个账号只能说明方向对了,不能说明所有边缘数据都已经被照顾到。
后面两个小时,伟源按账号类型把完整回归又跑了一轮。小马哥继续跟进剩余特殊账号的归属,我给监控补了一组业务层面的观察:不只看列表接口有没有报错,还要看有历史记录的企业账号查询结果是否突然归零,以及修复前后任务数量有没有异常变化。
服务器说成功,只能证明请求走完了。
用户该看到的数据也回来了,才算这条链路真的成功。
下午四点多,剩余账号全部确认完成,历史数据也按同样的规则补齐。上线后的新任务仍在稳定生成,队列没有积压,任务成功率也没有因为这次修复出现波动。
产品又陆续收了几轮反馈,除了一个提示文案不够清楚、一个表格在小屏幕下显得有点挤,没有再出现影响使用的问题。
小马哥靠在椅背上,终于把上午那句话说完整了。
“这回能说了吧?确实比第一次熟练。”
我看着监控,没有反驳。
确实熟练了。
但我也更清楚,熟练不代表 Bug 会因为认识你就绕路走。它只是让你在问题出现时,不再先跟着问题一起乱。
企业端上线以后,我最明显的感受,不是并发更大,也不是接口更多。
是用户对“稳定”这两个字的理解不一样。
C 端用户点一次没反应,可能刷新一下,退出重进,实在不行就骂一句不好用。企业用户不一样。一个账号后面可能有好几个人在协作,一批历史任务可能还要被继续筛选、确认和使用。你这里少一条数据,对他们来说不一定只是页面空了一块,也可能是前面的工作突然接不上了。
所以 C 端教会我怎么扛住真实用户,企业端又往前推了一步:不仅要让功能能用,还得让数据前后接得上,让同一套结果今天能看,明天也能看。
稳定不是监控面板一直绿色。
是用户不用反复确认,你这次给他的东西,下一次还在不在。
傍晚,我们把上线观察期的问题重新过了一遍。我新建了一份复盘文档,没有只写“早期账号历史数据缺失,已修复”这么一句。
我把它拆成了几项:
- 上线前增加新账号、早期试用账号和多身份账号的数据矩阵;
- 所有历史数据迁移必须同时校验数量、归属和可见范围;
- 监控不能只看接口成功率,要补用户实际查询结果;
- 企业身份关系发生变化时,必须有明确的数据处理和复核记录;
- 无法确认归属的数据禁止用宽查询临时兜底。
伟源在下面补了回归用例和责任人,小马哥把业务侧账号确认流程也加了进去。我们又把下一轮优化排出来:先做全量历史数据巡检,再补企业账号关系变化后的自动校验,最后把几类业务异常接进告警。
写完这些,天已经暗了。
办公室里还有人在走动,窗外高新园的楼一盏盏亮起灯。我把当天最后一轮监控截图贴进文档,任务成功率、队列长度和结果回写都很平稳。上午那几位异常用户也已经恢复,产品群里暂时没有新的问题。
我往椅背上一靠,终于把那口从早上提到现在的气放下来一点。
第一次 C 端上线时,我学会了上线以后别急着庆功,先看用户到底怎么用。
这一次,我又学会了绿色监控不等于一切正常,还得顺着用户的数据往前后多看几步。
经验这种东西,当时拿命熬的时候只觉得贵。等它真在下一次出问题时帮你少走一圈弯路,才知道那些复盘文档并不是写给领导看的,是以前那个狼狈的自己,给后来的自己留的排障说明书。
我合上电脑,拿起手机,给小璇发了条消息:
“C 端经验没白学,企业端也能跑。”