站点运营

站点运营:缓存與 CDN 自查,蜘蛛拿到的可能不是最新那版

缓存和 CDN 让頁面訪問更快,但也可能让蜘蛛讀到舊版本甚至空壳頁。這篇從整頁缓存、错誤狀態缓存、登入態差异、TTL 設定几個角度整理了一份自查清單,並說明怎么用日誌和不同 UA 請求,確認蜘蛛實际拿到的是什么内容。

站点运营

站点运营:缓存與 CDN 自查,蜘蛛拿到的可能不是最新那版

很多站点在排查抓取異常时,會先看服務器日誌、robots.txt 和站点地图,却很少想到另一层:蜘蛛拿到的 HTML,可能根本不是資料库里最新的那一版,而是缓存层吐出来的舊副本。缓存本身没有错,問题是缓存和抓取之間的關系没被管理好。

缓存把頁面變成了两份

開了一整頁缓存之後,同一個 URL 至少有两份内容:一份是源站刚生成的,一份是缓存节点上躺着的。用戶訪問时命中缓存,頁面秒開;而搜尋引擎蜘蛛来的时候,如果也命中同一份缓存,它看到的就是缓存生成那一刻的内容。内容更新後,蜘蛛可能過一阵才拿到新版本。

這件事本身不一定出問题。真正麻烦的是两種情况:缓存里存的是错誤頁面,或者不同訪問者拿到的内容差异過大。

几類常见的不一致

1. 缓存了错誤狀態

源站某次抖動返回 500,或者資料库连接失敗返回一個空壳頁,如果這類响應被 CDN 按正常頁面缓存下来,接下来一段時間所有訪問者和蜘蛛都會拿到這個错頁。常见表現是:日誌里同一個地址反复返回 200,但内容却是空的。

2. 带登入態的差异

有些主题或插件會根據 Cookie 判断登入狀態,未登入时展示摘要,登入後展示全文。如果缓存没有正确区分,蜘蛛(通常不带 Cookie)可能拿到一份權限受限的版本,正文大面积缺失。

3. TTL 设得太長

把 HTML 的缓存時間设成几天甚至几周,适合更新不频繁的静態頁,但對栏目首頁、文章頁就不合适。新發布的内容如果只在源站可见,蜘蛛抓到的還是舊版,發現和收錄都會被拖慢。

4. 地域與设备分流被缓存串味

多語言站点按 IP 判断語言、移動端返回精简版 HTML,這類分流如果和缓存策略没配合好,可能让蜘蛛在同一個地址上反复拿到不同語言的頁面,導致它對這個地址的主版本判断摇摆。

自查清單

  1. 用一個干净的、不带 Cookie 的請求訪問核心頁面,检查返回内容是否完整,正文、标题、内鏈是否都在。
  2. 換一個常见的搜尋引擎蜘蛛 UA 再請求一次,對比两次返回的 HTML 是否一致。
  3. 故意請求一個不存在的地址,確認返回的是 404,而不是一個被缓存的 200 空頁面。
  4. 检查 CDN 後台有没有開啟错誤响應缓存,如果有,確認 5xx 的缓存時間是否被压到很短的秒級。
  5. 核對 Cache-Control 里的 s-maxage 與實际内容更新频率是否匹配,栏目頁和文章頁可以给不同档位。
  6. 看服務器日誌里蜘蛛抓到的頁面大小分布,如果同一批地址响應体忽大忽小,值得查一查缓存分层。

响應头可以怎么设

HTML 文档一般不建议让邊缘节点長時間缓存。比較稳妥的做法是给一個較短的 s-maxage,配合 stale-while-revalidate,让节点在回源更新的同时繼續提供舊内容,避免用戶等待。真正需要長缓存的,是图片、CSS、JS 這類带版本号或指纹的静態资源,它們改名後地址會變,不容易出错。

同时留意 Vary 头。如果站点按 User-Agent 或 Accept-Language 返回不同内容,Vary 要寫清楚,否則缓存可能把 A 的版本發给 B。寫错 Vary 也會让缓存命中率下降,回源压力反而變大。

怎么確認蜘蛛看到的是什么

最直接的办法是拿日誌说话。挑几個重点地址,记錄蜘蛛訪問的時間点、返回狀態碼和响應体大小,再和自己的手動請求做對比。如果响應体大小長期稳定,但頁面内容其實已经更新過,基本可以判断命中的是舊缓存。也可以临时给這類地址加上較短缓存或直接绕過缓存,观察抓取到的内容是否随之變化。

另外,站点地图里的 lastmod 如果和缓存里實际的版本對不上,也容易让蜘蛛产生誤判。更新内容之後,顺带確認一下缓存有没有被主動刷新,比等着 TTL 自然過期更省事。

缓存的目标是让用戶更快看到内容,而不是让蜘蛛一直看到舊内容。把缓存時間、回源策略和内容更新节奏對齐,抓取和展示才會各自正常。