灰度发布时死链查询结果干净,全量上线后却出现大量死链,通常不是工具失灵,而是灰度样本没有覆盖到全量才触发的例外路径。判断该不该因为灰度通过就全量放行,取决于你的死链来源是否集中在少数模板、以及这些模板在灰度流量中是否真的被走到。
死链查询的价值不在于给出一个总数,而在于让你判断风险是否随流量规模变化。灰度阶段可以用两种做法,选择依据是死链的分布形态。
区分这两种条件的方法,是在灰度期间不只看死链总数,而是看死链命中的 URL 是否落在灰度实际访问过的路径集合内。如果灰度访问过的路径全部正常,而全量后出问题的路径在灰度日志里从未出现,那问题就属于条件二,灰度结论不成立。
只记录“有无死链”不足以支撑放行决定。灰度期间需要留下一份可对照的路径清单,让全量后的死链能反查到灰度是否覆盖。
做完这一步,你会得到一张覆盖表。全量后如果死链全部落在“灰度未覆盖”的格子里,说明灰度设计本身有盲区,而不是发布动作有误。这个结论会直接改变下一步:不是回滚,而是补一次针对盲区的定向灰度。
假设某站点改版商品列表,灰度只放给 1% 的匿名访客,死链查询显示零异常。全量后登录用户访问第 5 页以上筛选组合时出现死链。回看灰度记录,登录态和深层分页都未被请求过。这里灰度没有错,只是它的样本结构决定了它无法回答登录态下的分页问题。此时合理的动作是补一次带登录态、强制翻到深层的定向灰度,而不是直接回滚整个改版。
反过来,如果灰度已经覆盖了登录态和深层分页,死链查询仍然为零,全量后却出现同类路径的死链,那才需要怀疑缓存、CDN 回源或数据同步这类只在全量压力下才显现的环节。
全量后死链增多,常见的合理解释不止一种,死链查询数字上升本身不能单独证明某个环节出了问题。
把死链按这三类归因,再决定动作:覆盖盲区补定向灰度,规模触发查缓存与超时阈值,数据变化查同步时序。三种原因对应三种不同的修复位置,混在一起处理只会反复回滚。
在灰度结束、准备全量之前,做一次盲区补测:从死链查询的历史结果里挑出最容易在全量暴露的参数组合,主动构造请求打到灰度环境。如果这些请求返回正常,放行的把握来自覆盖,而不是来自灰度流量的大小。如果返回异常,你就在全量前拿到了例外,代价远小于上线后回滚。
这个动作的结果会直接决定下一步是放行、补测还是缩小改动范围。灰度通过与否本身不是结论,覆盖是否完整才是。