现场是这样的。站点从 WordPress 换到 Ghost,新站地址是 /post-slug/,旧站是 /archives/12345.html。上线时只导入了内容,没有做地址映射,三千篇旧文的收录全部指向 404,搜索来的流量一周掉到原来的三成。

中间走过弯路,把「新站上线前没有做全量 URL 对比」当成主因,改完现象没变。

排查方向其实有限,先把可能性排一排。两套系统的永久链接规则完全不同,导入时没有生成映射表;旧站的数据备份很快就删了,映射关系无从重建;sitemap 直接换成了新地址,旧地址没有任何过渡。

动手时先统计旧站地址还有多少在被请求

awk '$9==404{print $7}' access.log | sort | uniq -c | sort -rn | head -20

从旧站备份里导出 ID 与 slug 的对应关系

SELECT ID, post_name FROM wp_posts WHERE post_status='publish';

生成 301 规则并逐条落地

rewrite ^/archives/([0-9]+)\.html$ /$1/ permanent;

末了按周观察旧地址的 404 数量是否下降

awk '$9==404{c++} END{print c}' access.log

恢复的判定其实很直接。旧地址逐条 301 到新地址,404 从每天上万降到几百,自然流量在六周内回到迁移前的八成。

这里还有个坑。换系统的风险不在内容导入,而在地址映射,导入前先把旧站 URL 全量导出,这一步省不得。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。

作者 9823189