灰度流量只覆盖一部分入口时,测试死链接的结果只能证明“被抽到的那部分”没有断链,不能证明全量发布后所有旧内容、旧系统或旧合作关系都处理干净。真正暴露例外的,通常是灰度里那些没被抽中的路径、只在特定条件才返回 404 的链接,以及被 robots.txt 挡住却仍出现在站内导航里的地址。下面用一个假设情境把决策过程讲清楚。
假设一个站点要把旧产品线整体下线,同时保留仍然有参考价值的教程页。团队先做 10% 灰度:随机放出一部分用户访问新版导航,并在灰度环境里跑一遍测试死链接。扫描结果显示没有 4xx,于是准备全量发布。
问题出在灰度样本的构成。随机抽样偏向高频入口,而旧内容大多藏在低频路径:历史活动页、旧版帮助中心、合作方互换的友情链接。这些地址在灰度里几乎没被访问,扫描器也没有把它们当作起点。全量发布后,低频路径才第一次被真实用户和爬虫同时触达,例外集中出现。
要让灰度真正有用,需要按“路径类型”而不是“访问量”来分层,并分别留下可复查的证据。
可区分的原因证据是:返回 404 说明目标确实不存在;返回 200 但内容为空说明路由还在、内容已撤;301 到不相关页面说明跳转规则写得太粗。三者对应不同的修复动作,不能混为一谈。
把待处理地址按来源分层:主导航、正文内链、站点地图、历史外链、合作方互换链接。灰度阶段对每一层各抽一部分,而不是整体随机抽 10%。动作的结果会直接影响下一步:如果某一层在灰度里就出现 404 或错误 301,说明该层的退出规则还没写完,应先修规则再扩大流量;如果各层都干净,才把灰度比例提高,并把扫描起点换成站点地图加历史 URL 列表。
这里要注意,站点地图不保证收录,它只是给抓取提供线索;把站点地图当作“已发布地址全集”会再次漏掉历史外链。robots.txt 的抓取限制也不等于可靠的索引移除:被禁止抓取的地址仍可能因为外部引用而出现在结果里,所以不能用一条 Disallow 代替对死链接的实际处理。
全量之后不要只看一次扫描的总数。更有用的做法是对比灰度与全量的差异清单:全量新增的 4xx 里,有多少来自灰度未覆盖的层。如果新增几乎全部集中在历史外链层,说明站内规则已经稳定,剩下的是站外引用问题,处理方式应转向联系合作方或保留跳转,而不是继续改站内路由。
还要区分“请求量归零”和“处理正确”。某个旧地址不再被访问,可能是因为入口已被移除,也可能只是因为爬虫还没重新抓取,或该地址本来流量就低。请求量、抓取量归零不能单独证明死链接已经处理妥当,需要结合状态码复查和入口检查一起判断。若涉及具体搜索引擎的支持差异,应分别核查,不要用一家引擎的表现推断另一家。
最后,保留仍然有价值的部分要单独标记。教程页、被外部引用的说明页可以保留并更新,其余地址再进入退出流程。这样灰度验证的就不是“有没有死链接”,而是“退出规则是否覆盖了所有路径类型”,全量发布后的例外才会真正收敛。