给蜘蛛池的入口站套上 CDN,是很多人顺手就會做的事:省带宽、抗压,顺便遮一下源站 IP。但套完之後往往會發現,蜘蛛的抓取表現和预期不太一样——有时更顺,有时反而變差。原因大多不在 CDN 本身好不好,而在于蜘蛛拿到的到底是一份缓存副本,還是回源之後的實时内容。
蜘蛛請求也會命中缓存
CDN 节点不区分訪客是谁,只要 URL、請求方法、請求头组合匹配缓存键,就直接把副本返回。主流搜尋引擎的蜘蛛 UA 通常是公開的,节点不會因為它是蜘蛛就强制回源。也就是说:如果這個 URL 之前已经被別人或蜘蛛自己請求過,並且缓存還没過期,蜘蛛讀到的就是那份副本,源站根本没收到這次請求。
這本身不是坏事。副本稳定、响應快,蜘蛛讀取意愿一般不會差。問题出在副本已经不代表目前真實狀態的时候。
几種常见的回源行為及其影响
- 强制回源:每次請求都打到源站。抓取压力回到源站,但内容一定是最新的,适合入口頁需要频繁變更的场景。
- 長缓存且不刷新:蜘蛛長期讀到舊版本。如果入口頁的出鏈结构已经調整,蜘蛛看到的還是老連結,URL 發現效率會打折。
- 各节点獨立缓存:不同节点缓存過期時間不一致,蜘蛛從不同出口 IP 訪問,可能拿到内容有差异的几份副本。
缓存策略上比較稳的几條做法
- 入口頁 HTML 设一個偏短的缓存時間,比如几分钟到几十分钟,让内容更新能較快体現,同时又能挡住瞬时压力。
- 静態资源如 CSS、JS、图片可以放心長缓存,它們不承载出鏈關系。
- 明确区分狀態碼:正常頁缓存,301 可以缓存,但 5xx 和临时错誤別缓存,避免蜘蛛反复讀到错誤頁。
- 如果确實要按 UA 返回不同内容,務必在响應里声明 Vary,否則缓存會串味,把 A 版本發给 B 類訪客。
缓存不是用来骗蜘蛛的,而是告诉它:這份内容在這個時間窗口内是可信的。窗口设得太長,你就是在让蜘蛛讀歷史。
容易被忽略的几個坑
- 节点回源失敗时返回自定义错誤頁,但狀態碼寫的是 200,蜘蛛會把错誤頁当正常内容處理。
- CDN 預設開了防盗鏈或訪問频率限制,蜘蛛密集抓取时被拦,返回 403,日誌里表現為蜘蛛来過但没讀成。
- 源站做了 IP 白名單,只放行 CDN 回源段,结果蜘蛛直连源站时被拒——本来没事,改配置之後反而出事。
- 換 CDN 厂商或調整节点後没有清缓存,舊副本還留在节点上。
怎么驗證蜘蛛讀到的是哪一份
- 用蜘蛛 UA 手動請求一次入口頁,看响應头里的缓存命中标识,例如 X-Cache、Age。
- 對比源站日誌與 CDN 日誌:源站請求數遠小于 CDN 侧請求數,說明大部分是命中缓存。
- 改動入口頁内容後,按缓存時間等待,再用蜘蛛 UA 复测,確認版本已经更新。
- 观察一段時間内不同出口 IP 的返回是否一致,不一致就回头查节点缓存策略。
把 CDN 当成入口站的一层缓冲是合理的,前提是你清楚蜘蛛在什么情况下拿到的不是源站刚生成的那份 HTML。花十分钟核對一次缓存头,往往比反复調整入口頁结构更有效。