缓存是站点运营里最容易被忽略、又最容易出問题的一环。配好了,它能把服務器压力降下来、让頁面打開更快;配错了,蜘蛛和用戶看到的可能是几周前的舊内容,甚至是一個早就修好的报错頁。
缓存本身不改變抓取規則,但它决定了你在什么时候看到什么版本。当一個頁面已经修复、已经更新、已经下架,而缓存层還在往外發舊副本时,排查就會變得非常別扭——後台明明是對的,线上却是错的。
缓存最常出問题的几個位置
- CDN 邊缘缓存:把 HTML 文档当成静態资源做長缓存,max-age 设成七天甚至一個月,内容改了邊缘节点還不知道。
- 反向代理與網關缓存:整頁缓存下来,却没有按 Cookie 或登入態区分,登入用戶可能看到游客版本,甚至看到別人的頁面。
- 應用层缓存:片段缓存、對象缓存過期時間太長,栏目列表和推荐位長期不刷新。
- 浏览器缓存:静態资源没問题,但 HTML 也设了長缓存,用戶不强制刷新就看不到更新。
逐項自查清單
1. HTML 文档是否被当静態资源長缓存
图片、CSS、JS 用带版本号的長缓存是好事,但 HTML 文档通常不该這么做。如果响應头里對文档设了很長的缓存時間,内容更新後,邊缘节点和浏览器都會繼續用舊副本。文档類地址更适合較短的缓存時間配合协商缓存,或者交给 CDN 的刷新接口统一控制。
2. 错誤狀態是否被缓存
比缓存舊内容更麻烦的是缓存错誤。404、500、503 只要带上可缓存的响應头,就會被节点存下来。後台已经修好,外面看到的還是报错頁。至少要保證 5xx 不落缓存,回源異常时也不要把结果寫進缓存。
3. Vary 與 UA 区分是否到位
同一個地址對不同设备可能返回不同的 HTML。如果缓存键只看 URL,移動端用戶可能拿到桌面版,反過来也一样。检查 Vary 头是否包含必要维度,或者干脆用不同地址、子域区分移動版本。
4. 登入態與個性化内容
带 Set-Cookie 的响應、包含用戶個人信息的頁面,應该标记為私有或不做缓存。把它們缓存到公共节点上,轻則顯示错乱,重則泄露信息。
5. 带參數地址的缓存键
追踪參數、排序參數、會话參數會制造大量近似地址。如果缓存键把這些都算進去,节点空間被稀释;如果不算,又可能把不同内容混在一起。對無關參數做規范化,是缓存治理和 URL 治理可以一起做的事。
6. 改版與下线後的清理流程
内容改版、栏目合並、頁面下架之後,缓存不會自動知道。要有一個明确的刷新動作:按地址提交刷新、按目錄批量清理,必要时改文件名或加版本參數。少了這一步,下线頁面可能長期對外可见。
怎么快速排查
- 用命令行工具請求同一個地址两次,观察响應头里的 Age 或缓存命中标记是否在變化。
- 換一個 User-Agent 再請求一次,比較返回的 HTML 是否一致。
- 故意請求一個不存在的地址,连續两次,看第二次是不是直接返回缓存的 404。
- 對比源站和 CDN 返回的响應头,確認缓存策略是不是在某一层被改寫。
- 内容更新後立刻訪問一次,確認看到的是新版本,而不是节点上的舊副本。
几個容易踩的坑
- 只测首頁。首頁往往有單獨策略,栏目頁和詳情頁才是問题集中区。
- 只看浏览器。浏览器有本地缓存,带一個随机參數請求一次,才能看到节点的真實狀態。
- 把刷新当常規手段。频繁全量刷新會让缓存失去意义,回源压力反而更大。
- 把缓存和收錄混為一谈。缓存放的是副本,不替你做收錄决定,但它决定了蜘蛛当场抓到的是哪一版。
缓存的目标是让正确的版本更快地到達用戶和蜘蛛,而不是让某一個版本永遠停留。定期花十分钟检查一次缓存策略,比起事後追查线上為什么還是舊的,要省事得多。