搜索抓取

CDN 缓存与蜘蛛抓取:日志对不上和抓到旧页面的两种情况

源站日志里蜘蛛记录偏少,未必是蜘蛛没来,可能是请求被 CDN 缓存接走了;反过来,HTML 被长缓存时,蜘蛛又可能反复读到旧快照。本文梳理这两种错位怎么分辨、用哪些响应头和日志核对,以及页面类内容在缓存策略上该如何区分处理。

搜索抓取

CDN 缓存与蜘蛛抓取:日志对不上和抓到旧页面的两种情况

不少站点在源站日志里核对蜘蛛抓取量时,会发现数字比预期小很多:Sitemap 提交了几千条 URL,日志里只有几百条蜘蛛记录。这时候先别急着判断蜘蛛没来,很可能是请求被 CDN 或反向代理的缓存接走了,压根没落到源站。

蜘蛛的请求不一定落在源站

正常链路是:蜘蛛发起请求,DNS 解析到 CDN 节点,节点判断缓存是否命中。命中就直接返回,源站不产生这条访问日志;没命中才回源,源站才记下一笔。也就是说,源站日志里的蜘蛛次数实际上是缓存未命中的次数,它天然小于真实抓取次数,抓取越频繁的页面,这个偏差越明显。

情况一:命中缓存,源站日志缺记录

这种情况本身不一定是问题,缓存命中反而是好事,能减轻源站压力。麻烦的是把它误读成抓取不足,然后去改内链、加提交接口,做的都是无用功。

  • 看响应头:Age 有值说明来自缓存,X-Cache、CF-Cache-Status 之类的自定义头也能直接标明命中与否。
  • 看 CDN 侧日志:多数 CDN 提供访问日志或分析面板,按 Spider 的 User-Agent 过滤,才能拿到接近真实的抓取次数。
  • 抽样验证:用 curl 带上蜘蛛 UA 请求一个已知被抓过的 URL,观察返回头和源站日志里是否同步出现记录。

只有把 CDN 日志和源站日志叠起来看,抓取覆盖率的核对才站得住脚。

情况二:缓存住旧版 HTML,蜘蛛拿到过期内容

另一类问题更隐蔽:如果 HTML 被设置了很长的缓存时间,蜘蛛每次来拿到的都是同一份旧快照。内容更新了,lastmod 变了,Sitemap 也重新提交了,但蜘蛛读到的仍是旧版页面。它顺着旧页面上已经删掉的内链继续走,新加的入口自然发现不了。

哪些页面不适合长缓存

  • 首页、栏目页、列表页:这些页面承担 URL 发现职责,缓存时间建议短一些,或采用短周期加回源校验的方式。
  • 新发布的详情页:上线初期缓存可以设短一点,或者发布后主动刷新。
  • 带登录态或个性化内容的页面:用 Vary 区分,或者干脆不缓存。

缓存失效的配合动作

发布新内容时主动 purge 对应 URL;把 HTML 的 s-maxage 控制在一个较短区间,而不是和图片、CSS 用同一套长缓存规则;同时保留 ETag 与 Last-Modified,让节点回源校验时可以走 304,减少实际传输量。静态资源与页面用两套策略,是最省心的做法。

核对顺序可以固定下来

  1. 带蜘蛛 UA 抽样请求目标 URL,先看 Age 和缓存状态头,确认请求停在哪一层。
  2. 取同一时间窗,对比 CDN 日志与源站日志中的蜘蛛请求数,看差多少、差在哪些目录。
  3. 检查 Cache-Control 对 HTML 的设置,确认是否和静态资源混用了同一套规则。
  4. 发布新内容后,隔一段时间再用蜘蛛 UA 抓一次,确认拿到的版本已经更新。
缓存问题很容易伪装成「蜘蛛不来」,先确认请求到底停在网络哪一层,再谈内链、Sitemap 这些优化,顺序反了会白做很多事。

小结

CDN 缓存和蜘蛛抓取之间有两处容易错位:一处是日志,缓存命中让源站看不到抓取;一处是内容,长缓存让蜘蛛看到旧页面。前者靠日志合并核对解决,后者靠区分页面与静态资源的缓存策略解决。把这两点理清,再去判断抓取覆盖率和 URL 发现问题,结论会可靠得多。