先别急着回滚。把修复动作、它依赖的前置条件、以及下游消费这份结果的人分开列出来,通常能发现异常不是修复本身造成的,而是某个下游仍在按旧假设读取数据。判断顺序是:确认修复改变了什么事实,再确认谁在消费这个事实,最后才决定保留、改写还是退出这次修复。
死链检查工具的输出通常被三类角色消费:执行改链的人、审核状态的人、以及把状态同步到其他系统的人。一次修复如果只改了链接目标,却让状态字段从“待处理”变成“已处理”,第二类和第三类角色的判断依据就变了。异常往往出现在这里,而不是链接本身。
可核对的做法是:把这次修复涉及的状态字段、跳转规则、排除名单各写一行,标注“谁依赖它”。如果某个下游只依赖“响应码”,而修复顺带改了“跳转层级”,那下游报错就属于预期外但可解释的结果。这一步做完,你才知道该修下游还是改修复。
保留适用于:异常只出现在单一消费方,且该消费方可以独立调整读取逻辑。此时修复本身是对的,只需让下游跟上。动作是给下游加一层兼容判断,观察它是否恢复正常;若恢复,说明依赖链断点已定位。
改写适用于:异常出现在多个消费方,且它们共享同一份中间结果。此时不该逐个改下游,而应改中间结果的生成方式,让新旧字段并存一段时间。前提是你确认旧字段仍有消费者,且能承受两份数据暂时不一致。
退出适用于:修复改变了不可逆的事实,例如批量替换了跳转目标,而下游无法在合理成本内适配。退出不是失败,而是承认这次修复的假设不成立。前提是你能把已改动的部分逐条还原,并且还原后不会再触发同一异常。
三种取舍没有优劣,只有前提是否成立。前提不成立时强行保留,只会把异常从一处推到另一处。
异常出现后,先收集三类证据,它们指向不同原因:
这三类证据不需要复杂工具,只需要在修复前后各记录一次各角色的读取结果。记录本身就是下一步决策的依据:如果证据指向消费侧,就改下游;如果指向中间结果,就改生成逻辑;如果指向延迟,就先不动。
假设某站把一批死链统一跳转到首页,同时把状态从“404”改为“301”。审核角色只关心“是否还有404”,看到301就认为已处理;而统计角色按“跳转层级”汇总,发现大量链接从一级跳转变成二级跳转,于是报表异常。
这里修复没有错,异常来自统计角色仍按旧层级读取。动作是:先确认统计角色能否接受二级跳转,若可以,改写它的汇总规则;若不可以,就退出这次统一跳转,改为逐条确认目标页。这个例子的假设是:两个角色读取的是同一份状态数据,但关注的字段不同。现实中字段可能更多,拆分方法相同。
多个角色对同一事实理解不同时,不要争论谁对,而是把分歧写成可核对的项目:谁在什么条件下读到了什么值,期望值是什么。每个项目对应一个动作,动作的结果决定下一步是保留、改写还是退出。
例如,若核对后发现分歧只存在于“跳转层级”这一个字段,就只针对该字段做兼容,不动其他部分。若分歧涉及多个字段,说明这次修复的改动面超出了预期,应优先考虑退出并缩小改动范围。核对项目的数量本身就是一个信号:项目越多,越说明修复的依赖链没有被提前理清。
最后,把这次核对结果记录下来,作为下次同类修复的前置检查项。依赖链不是一次拆完就永久有效,它会随消费方变化而重新缠绕。