很多蜘蛛池入口頁並不是直接暴露源站,而是挂在 CDN 或反向代理後面。搜尋引擎蜘蛛請求 URL 时,先到達邊缘节点;如果命中缓存,它拿到的是缓存副本,而不是源站實时生成的那份 HTML。這一点如果被忽略,就會出現“我在源站明明改好了,蜘蛛看到的還是舊内容”的困惑。
蜘蛛訪問 CDN 时發生了什么
CDN 的本质是在离用戶和蜘蛛更近的节点上放一份副本。节点判断請求能不能用缓存回答,能就直接返回,不能就回源站取一次,再按規則决定是否留存。對蜘蛛来说,它並不關心背後是源站還是邊缘节点,它只認這次 HTTP 响應里的狀態碼、响應头和正文。
命中缓存與回源
如果缓存未過期,邊缘节点直接返回舊副本;如果缓存已過期或不存在,节点回源。回源這一步如果源站响應慢、超时或报错,有些 CDN 會返回自己生成的错誤頁,而不是把源站的真實狀態透传给蜘蛛。蜘蛛看到的是一個 200 狀態碼,正文却是“服務暂时不可用”之類的提示,這種情况在入口頁上尤其容易被誤判為“頁面正常”。
缓存键决定“同一個 URL”的含义
缓存键通常由域名、路径、查询參數、請求头等要素组合而成。如果缓存键把某些查询參數也算進去,那么带參數的 URL 和不带參數的 URL 會被当成两個不同對象,各自缓存一份。對蜘蛛池入口頁来说,這可能導致同一批連結被拆成多個缓存變体,增加节点存储和回源次數,也让内容更新變得更难同步。
几類常见的缓存問题
- 缓存版本滞後:源站已经改了入口頁的連結或文字,邊缘节点還在返回舊副本。蜘蛛按固定频率来抓,拿到的仍是上一版内容。
- 缓存键包含無關參數:統計參數、来源标记等被算進缓存键,同一路径产生大量缓存變体,回源压力上升。
- 回源失敗返回 200:源站 5xx 或超时,CDN 用自己的错誤頁替代,蜘蛛收到 200,正文却是空壳或提示语。
- 错誤狀態被缓存:404、503 被节点缓存一段時間,蜘蛛下次来仍然拿到错誤頁,即使源站已经恢复。
- Vary 头設定不当:按 User-Agent 区分缓存时,蜘蛛拿到的可能是為浏览器准备的版本,或者反過来。
缓存头怎么设比較稳妥
入口頁不是静態资源,不建议設定過長的缓存時間。對于需要定期更換連結、調整模板的頁面,可以把 Cache-Control 设為較短的 max-age,配合 stale-while-revalidate 之類的策略,让节点在後台更新,而不是把舊副本長期挂在那里。若頁面内容對訪問者身份不敏感,尽量不要用 Vary: User-Agent,否則蜘蛛和普通訪客會各存一份,既浪費节点空間,也容易让两邊看到不一致的版本。
另外,源站的错誤狀態不要被 CDN 改寫成 200。回源異常时,宁可让蜘蛛看到真實的 5xx 或超时,也不要给它一個“看起来正常”的空頁。错誤頁被缓存後,清理起来往往比重新回源更麻烦。
判断入口頁是否被缓存拖累,不要只看源站日誌。源站日誌里可能只有 CDN 回源那几次請求,蜘蛛在邊缘节点命中缓存时,源站完全不知情。
驗證蜘蛛實际拿到什么
可以用几種方式交叉驗證:一是直接請求入口頁 URL,观察响應头里的缓存命中标记、Age、X-Cache 等字段;二是用與搜尋引擎蜘蛛相近的 User-Agent 發起請求,對比返回正文是否一致;三是在源站和 CDN 分別打日誌,看同一次抓取是否只到了邊缘、有没有回源。若發現缓存版本和源站不一致,先確認缓存键和缓存头,再决定是刷新缓存還是調整規則。
使用建议
- 入口頁上线前,先確認 CDN 缓存規則和缓存键設定,避免參數污染。
- 需要更新内容时,判断是改源站就够,還是必须同时刷新邊缘缓存。
- 不要把入口頁当成静態文件長期缓存,给蜘蛛留出看到新版本的机會。
- 回源異常时保留真實狀態碼,不要让 CDN 错誤頁伪装成 200。
- 定期抽查邊缘节点返回的正文,而不是只信任源站自测结果。
CDN 和缓存层本身不是問题,問题在于入口頁的内容更新节奏與缓存策略是否匹配。把缓存当作蜘蛛訪問鏈路中的一环来看,很多“蜘蛛没反應”的疑問會更容易定位。