先给结论:不要按“谁先配置”或“谁最后发布”来定责,而要按“谁拥有该网址的最终输出格式”来定。具体做法是,在虚拟主机上为每条网址规则指定一个生成系统作为唯一责任方,其他系统只能读取或转发,不能改写。若两个系统都能改写同一路径,规模化后必然出现规则互相覆盖,个别样本正常只是暂时没撞上。
拿你手里任意一个已上线的页面,检查它从请求到最终响应经过了几层。常见情况是:虚拟主机上的伪静态规则生成一层,应用框架的路由生成一层,站点地图或站内链接生成一层。三层各自都能决定 URL 长什么样时,问题就埋下了。
判断依据不是看配置文件有多少条规则,而是看同一路径能否被两处独立改写。例如一个详情页既能通过 /item/123 访问,又能通过带参数的 /product?id=123 访问,且两者都返回正常内容,这就是两个系统都在生成网址的信号。此时不要急着删规则,先记录每个系统实际输出的 URL 形态,作为后续定责的证据。
配置顺序不可靠,因为发布节奏、缓存刷新、重启时间都会改变实际生效顺序。可靠的做法是给每条网址规则声明一个输出所有者,规则如下:
举个假设例子说明取舍。假设虚拟主机伪静态负责把 /old-a 重写到应用入口,而应用框架又自己生成了 /new-a,并把它写进页面链接。如果两者都保留,站内链接指向新形态,外部旧链接走重写,短期看似都通。规模扩大后,新页面由框架生成、旧页面由伪静态兜底,同一类内容出现两种 URL,责任方就模糊了。此时应把框架定为唯一责任方,伪静态只保留一条从旧到新的重写,不再生成新形态。
选定责任方后,按下面顺序处理,每一步的结果决定下一步:
动作的结果会直接影响下一步:如果停止非所有者生成后,站内链接和站点地图里的 URL 仍然混杂,问题就不在生成层,而在引用层,需要单独处理引用来源。这一步不做,后面无论怎么调规则都会反复。
个别样本成立不代表规则可以照搬。以下边界需要提前写清:
当样本量小、路径少时,两个系统并存可能看不出冲突;一旦页面数量、模板数量或语言版本增加,例外就会成倍出现。判断是否已经越界的信号是:同一内容存在两种以上可访问 URL,且无法用一条规则解释全部情况。出现这个信号,就说明唯一责任方没有真正落地。
唯一责任方不是一次配置就结束。每次新增模板、新增语言或更换发布流程后,都要重新确认输出形态是否仍然唯一。验证时以实际响应为准,不以配置文件为准,因为配置可能被缓存、被覆盖或被其他层拦截。
如果验证发现某条路径又出现第二种形态,先判断它是引用层引入的还是生成层引入的。引用层问题改链接来源,生成层问题回到所有权声明。把这两类分开处理,才不会在规模化后反复回到同一个冲突。