唯一责任方应该是最终对外输出网址规则的那一层,而不是生成规则的各个上游系统。判断依据只有一条:谁把URL写进发给Google的响应、站点地图或页面链接,谁就对这条URL负责。上游可以继续生成候选,但必须经过一层归并和签发,否则退出旧系统时会出现两套规则同时生效、互相覆盖。
第一种条件:旧系统仍在产生URL,但这些URL已经不需要被收录。此时唯一责任方应设在归并层,由它决定旧URL是返回404、410还是301到新地址。旧系统本身不直接对外输出,只提供候选清单。
第二种条件:旧系统已经停止产生新URL,但历史URL仍有外链或仍有用户访问价值。此时唯一责任方应设在保留侧的规则签发层,由它把仍然有效的部分映射到新地址,其余部分交给归并层统一处理。两种条件的差别在于:前者要切断旧系统的对外输出,后者要保住旧URL的可达性。
选择依据可以落在一个可观察的证据上:如果旧URL在Google Search Console的抓取统计里仍有请求,但站点地图里已经不再出现,说明对外输出已经切换,剩下的是历史存量;如果抓取请求和站点地图同时出现旧URL,说明两套规则都在生效,此时不能直接删旧系统,必须先确定归并层是否已经接管。
具体动作是给URL规则加一个签发步骤。上游系统只写入候选表,字段至少包含URL、来源系统、目标状态和生效时间。归并层读取候选表,按优先级输出最终规则,再写入对外文件。对外文件只允许一个写入者,其他系统只能读。
这个动作的结果直接决定下一步:如果归并层输出的规则与旧系统直出的规则冲突,冲突会暴露在候选表里,而不是暴露在Google的抓取结果里。先修候选表,再改对外文件,可以避免一边删旧规则一边发现新规则没生效。
假设一个短例子:旧CMS生成/old/a,新系统生成/new/a,两者都指向同一篇仍有价值的内容。归并层把/old/a标为301到/new/a,把旧CMS的直出关闭。此时唯一责任方是归并层。若旧CMS仍在直出/old/a且返回200,归并层的301不会稳定生效,因为两个响应可能交替出现。
退出旧系统不等于全部删除。仍然有价值的部分通常包括:有稳定外链的旧URL、用户仍在访问的入口页、以及被其他系统引用的资源地址。这些例外不能由上游系统自行决定保留,必须由归并层签发,并记录保留原因和复查时间。
实施上可以给例外加一个单独的状态,例如keep,与redirect、gone并列。归并层按状态输出,旧系统不再参与判断。这样做的结果是:当旧合作关系结束、旧系统下线时,例外仍然由归并层控制,不会因为旧系统关闭而失效。
例外也需要边界。robots.txt的抓取限制不等于可靠的索引移除,站点地图不保证收录,这两点在这里的含义是:即使归并层把某个旧URL标为保留,也不能用robots.txt代替状态码处理,更不能假设放进站点地图就会被收录。保留只表示可达,不表示一定出现在搜索结果里。
当出现同一URL两种状态时,排查顺序不是先改Google,而是先确认对外文件的写入者数量。可用的证据包括:对外文件的最后修改时间、候选表里同一URL的多条记录、以及响应头里是否出现两套规则的特征。如果对外文件在短时间内被两个来源交替写入,唯一责任方就没有真正建立。
处理动作是冻结旧系统的写入权限,只保留归并层写入,然后重新生成一次对外文件。结果会体现在下一次抓取中:如果旧URL的状态不再来回变化,说明责任方已经唯一;如果仍然变化,说明还有第三个写入者,需要继续查候选表之外的直出路径。
需要注意,抓取量或请求量归零不能单独证明处理正确。它还可能来自抓取预算变化、外链减少、或Google暂时降低了对该路径的抓取频率。要确认规则生效,应结合响应状态、对外文件内容和候选表记录一起看,而不是只看一个统计数字。
只有在系统之间边界清晰、且不会写入同一对外文件时,才可以保留多个责任方。例如旧系统只负责生成候选、归并层只负责签发、新系统只负责接收跳转,三者各写各的表,不交叉写对外文件。这种情况下,唯一责任方仍然是归并层,其他两方是候选来源和接收方,不是规则签发方。
如果无法做到边界清晰,就应把旧系统的对外输出直接关闭,只保留候选生成,直到归并层能够独立签发全部规则。这样做的代价是短期内旧URL可能返回404或410,但换来的是责任唯一,后续保留哪些、跳转哪些都可以在一个地方决定,而不是在多个系统之间来回确认。