很多站点都會遇到這種情况:後台顯示已经發布,編輯在预览里也看到了新版本,但訪客看到的、搜尋蜘蛛抓到的,還是几小时甚至几天前的舊頁面。這时候第一反應往往是“是不是没發布成功”,于是反复点一次發布,结果問题依舊。多數情况下,問题不在發布环节,而在内容到訪客之間经歷的那几层缓存。
缓存不是故障,是没對齐
缓存本身是好事,它把重复計算的结果存下来,减少服務器压力,也让頁面打開更快。麻烦的是,当内容更新时,如果缓存层没有同步失效,新舊版本就會同时存在:編輯看到新的,部分用戶看到舊的,不同地区的 CDN 节点還可能各说各话。
所以真正要做的,不是把缓存一關了事,而是让“什么内容、缓多久、什么时候必须失效”這三件事有明确規則。
分层自查清單
1. 浏览器缓存與缓存头
- HTML 文档的 Cache-Control 是否设了過長的 max-age。正文頁通常不适合让浏览器長時間缓存,頁面級内容變動频繁时尤其要注意。
- 静態资源(CSS、JS、图片)可以長缓存,但文件名里建议带版本号或内容指纹,否則更新後用戶拿到的還是舊文件。
- 检查是否同时存在 ETag 與 Last-Modified,两者判断逻辑不一致时,部分客戶端會一直認為自己手上的副本仍然有效。
2. CDN 层
- 哪些路径被規則判為可缓存,哪些被排除。常见的坑是把整站 HTML 一起纳入缓存,却在更新时只刷新了首頁。
- 刷新方式的区別要弄清楚:URL 刷新只清具体地址,目錄刷新會影响一批頁面。频繁全量刷新既慢又消耗額度,最好按栏目分批處理。
- 回源策略是否合理。回源频率過高會让源站压力變大,過低又會導致内容迟迟不更新。
- 如果 CDN 會压缩或改寫 HTML,確認缓存的是改寫前還是改寫後的版本。
3. 服務器端缓存與對象缓存
- 頁面缓存(如整頁静態化、反向代理缓存)的失效規則是按時間触發還是按事件触發。
- 對象缓存、查询缓存是否在内容儲存时被主動清理。很多系統只在特定操作後才清缓存,批量導入或直接改資料库时不触發。
- 多台應用服務器之間是否存在缓存不同步,導致刷新後請求落到另一台、仍然返回舊内容。
4. 頁面自身的静態化产物
- 如果站点會生成静態 HTML 文件,確認新内容是否覆盖了舊文件,而不是生成到了另一個目錄。
- 检查是否存在多份同名模板产物,實际對外服務的可能不是刚更新的那一份。
更新後的驗證顺序
- 先在源站直接訪問,用带随机參數的地址排除本地缓存干扰,確認源站返回的是新版本。
- 再通過 CDN 域名訪問,观察响應头里的缓存命中狀態和過期時間。
- 換一個網絡环境或使用匿名窗口再看一次,確認不是本机缓存造成的错觉。
- 抽查同栏目下的其他頁面,確認刷新范围没有波及無關内容,也没有漏掉應该更新的頁面。
- 把這次更新的缓存處理方式记進發布流程,下次同類内容按同样的步骤走。
和抓取、收錄的關系
缓存不同步對搜尋蜘蛛的影响是間接的:蜘蛛拿到的是舊版本,就可能把已经修改過的标题、描述、正文重新当成舊内容處理。這不意味着更新一定不會生效,而是會拖慢變化的传递速度,也可能让頁面在搜尋端的呈現長期落後于實际内容。
把“内容發布”和“缓存刷新”当成同一個動作的两個步骤,而不是两件事。發布完成後顺手確認一次缓存狀態,比事後反复排查省事得多。
把規則寫下来
缓存策略最怕的是只存在于某個人脑子里。建议在运维或發布文档里固定几行内容:哪些目錄可以長缓存,哪些必须短缓存,更新某類内容时刷新哪些路径,由谁执行。規則稳定之後,編輯只管寫内容,技術只管维護規則,中間那层不确定性就少了很多。
另外,缓存刷新不需要每次都做全站。大多數日常更新只涉及一两個栏目,按范围刷新既快又不容易誤伤。真正需要全量刷新的场景其實很少,通常是模板、样式或導航结构整体調整的时候。