頁面更新了,訪客看到的還是三天前的版本;日誌里蜘蛛抓到的 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,改動就只能靠手動刷新,很容易漏掉一两個文件。
刷新策略怎么定
- 發布即刷:正文、标题、價格、库存這類頁面,發布流程里带上刷新動作。
- 失效後主動预热:刷新完主動請求一次,別让第一位訪客承担回源压力。
- 路径級刷新:栏目頁、列表頁用目錄刷新,比逐條提交 URL 更省事。
- 留下刷新记錄:谁在什么时候刷了哪些地址,出問题时能對帳。
一份可执行的自查清單
- 抽查十個近期更新過的 URL,看缓存狀態和 Age 是否合理。
- 確認缓存键里的參數都有實际作用,没有混進會话标识。
- 检查移動端與桌面端返回的 HTML 是否被正确区分。
- 核對静態资源是否带版本号或哈希,長 TTL 是否與之一致。
- 確認 404、410、301 這類响應不會被長期缓存。
- 確認登入態、後台、购物车等個性化頁面不進入公共缓存。
- 確認發布流程里有刷新步骤,有明确负责人和回滚预案。
提示:缓存不是越短越安全。TTL 調得太短,回源压力上升,蜘蛛集中抓取时反而更容易超时。先观察真實命中率和回源量,再决定要不要動這個值。
和蜘蛛的關系
蜘蛛抓到的 HTML 同样来自缓存层。如果栏目頁被缓存了很久,新發布的文章可能在列表里迟迟不出現,也就少了一個被發現的入口。给列表頁設定比詳情頁更短的 TTL,通常是比較稳妥的做法。同时也要清楚,刷新缓存只保證蜘蛛拿到的是最新版本,至于什么时候来抓,仍由搜尋引擎自己决定。