站点运营

站点运营:CDN 缓存與刷新自查,別让舊頁面一直發给訪客和蜘蛛

頁面更新了,訪客和蜘蛛看到的却還是几天前的版本,問题常常出在缓存层没對齐。本文梳理浏览器、CDN 邊缘节点、源站這几层缓存的区別,說明缓存键、Vary 头、長 TTL 等容易踩的坑,並给出一套發布刷新策略和可执行的自查清單,让新内容及时生效,同时不牺牲命中率。

站点运营

站点运营:CDN 缓存與刷新自查,別让舊頁面一直發给訪客和蜘蛛

頁面更新了,訪客看到的還是三天前的版本;日誌里蜘蛛抓到的 HTML 里,還挂着已经下线的活動入口。這類問题往往不是程序寫错了,而是 CDN 缓存和源站之間没對齐。缓存本身是好事,它让站点扛得住流量,也让蜘蛛的抓取更快,但它需要一套明确的刷新規則,否則舊副本會一直在邊缘节点上待着。

先分清缓存鏈路上有哪几层

很多“刷新没生效”的争论,其實是在讨论不同的层:

  • 浏览器缓存:由 Cache-Control、Expires、ETag 控制,影响的是回訪訪客。
  • CDN 邊缘节点缓存:按 URL、查询串、請求头(如 Accept-Encoding、Cookie)区分副本。
  • 源站或反向代理缓存:Nginx、Varnish、應用自身的頁面缓存,可能各存一份。
  • 静態资源版本:CSS、JS、图片常常單獨走一套策略,和 HTML 不同步。

自查时先確認“看到舊内容”具体卡在哪一层。可以看响應头里的缓存狀態和 Age 字段,對比命中與否、副本已存在多久,再决定是推刷新還是改配置。

几個容易踩的坑

缓存键里带了不该带的東西

如果缓存键包含會话 ID 或随机參數,命中率會掉到接近零;反過来,如果缓存键忽略了對内容有影响的參數,訪客可能拿到別的版本。篩選參數、分頁參數、語言參數,要明确哪些參與缓存键,哪些直接忽略。

忽略了 Vary 声明

同一 URL 對移動端和桌面端返回不同 HTML 时,需要正确的 Vary 声明,否則先到的那份會被發给所有人。驗證方式很简單:用不同 User-Agent 连續請求几次,看返回的 HTML 是否一致。

長缓存配了短變更

把静態资源 TTL 设成一年是常規做法,前提是文件名带哈希。如果文件名不變又设了長 TTL,改動就只能靠手動刷新,很容易漏掉一两個文件。

刷新策略怎么定

  1. 發布即刷:正文、标题、價格、库存這類頁面,發布流程里带上刷新動作。
  2. 失效後主動预热:刷新完主動請求一次,別让第一位訪客承担回源压力。
  3. 路径級刷新:栏目頁、列表頁用目錄刷新,比逐條提交 URL 更省事。
  4. 留下刷新记錄:谁在什么时候刷了哪些地址,出問题时能對帳。

一份可执行的自查清單

  • 抽查十個近期更新過的 URL,看缓存狀態和 Age 是否合理。
  • 確認缓存键里的參數都有實际作用,没有混進會话标识。
  • 检查移動端與桌面端返回的 HTML 是否被正确区分。
  • 核對静態资源是否带版本号或哈希,長 TTL 是否與之一致。
  • 確認 404、410、301 這類响應不會被長期缓存。
  • 確認登入態、後台、购物车等個性化頁面不進入公共缓存。
  • 確認發布流程里有刷新步骤,有明确负责人和回滚预案。
提示:缓存不是越短越安全。TTL 調得太短,回源压力上升,蜘蛛集中抓取时反而更容易超时。先观察真實命中率和回源量,再决定要不要動這個值。

和蜘蛛的關系

蜘蛛抓到的 HTML 同样来自缓存层。如果栏目頁被缓存了很久,新發布的文章可能在列表里迟迟不出現,也就少了一個被發現的入口。给列表頁設定比詳情頁更短的 TTL,通常是比較稳妥的做法。同时也要清楚,刷新缓存只保證蜘蛛拿到的是最新版本,至于什么时候来抓,仍由搜尋引擎自己决定。