站点运营

站点运营:CDN 缓存与刷新自查,别让更新后的页面还在发旧版本

内容更新后页面还是旧版本,多半是缓存层没跟上。本文梳理浏览器缓存、CDN 边缘缓存与服务端缓存的区别,说明如何通过响应头判断命中情况,如何为 HTML 与静态资源设置不同策略,以及更新后的刷新与验证流程,帮助站点运营把缓存纳入日常巡检清单。

站点运营

站点运营:CDN 缓存与刷新自查,别让更新后的页面还在发旧版本

把一篇文章改好了标题、补好了内链,发布之后自己看着没问题,但同事打开还是老样子,搜索引擎抓到的也可能是几天前的版本。这种“发布成功、页面没变”的情况,多数不是发布失败,而是缓存层还在拿旧副本。做站点运营的人,需要知道自己的站点到底有几层缓存,以及每一层什么时候会更新。

先搞清楚有哪几层缓存

一个访客看到的页面,通常会经过这几道关口:

  • 浏览器缓存:访客本地保存的副本,由响应头决定它多久不回来问服务器。
  • CDN 边缘节点缓存:离访客最近的机房保存的副本,命中时不回源。
  • 服务端缓存:页面缓存插件、反向代理、对象缓存等,在源站内部再存一层。
  • 数据库查询缓存:某些 CMS 会把查询结果暂存,内容更新后需要主动清理。

排查时按“离访客最近的一层”往回走,比盲目点一遍“清除缓存”更有效。

用响应头判断命中了哪一层

同样的地址连续请求两次,对比返回头就能看出不少信息。重点看这几项:

  • Cache-Control:max-age 有多长,是否带 s-maxage、stale-while-revalidate。
  • Age:副本已经在边缘放了多久,数字很大说明命中缓存。
  • X-Cache、CF-Cache-Status 之类的头:HIT、MISS、EXPIRED、DYNAMIC 直接告诉你结果。
  • Last-Modified、ETag:用于协商缓存,内容变了这两个值应该跟着变。
  • Vary:如果带了 Cookie 或 User-Agent,缓存会按维度分片,命中率明显下降。

如果更新内容之后 Age 一直不清零,说明边缘缓存没有被刷新;如果 Age 很小但内容还是旧的,问题更可能在源站那一层。

HTML 和静态资源应该用不同策略

一刀切的缓存设置往往两头不讨好:设短了,静态资源反复回源;设长了,文章改完迟迟不更新。比较常见的做法是分开处理。

  • HTML 页面:设置较短的 max-age,或者走协商缓存,让浏览器每次都回来确认一次。
  • 带指纹的 CSS、JS:文件名里带哈希或版本号,可以放心用一年以上的长缓存和 immutable。
  • 图片、字体:同样适合长缓存,但替换素材时要换文件名或加参数,不要直接覆盖原文件。
  • 带登录态或个性化的页面:不要做公共缓存,或者明确声明 private。

另外,栏目页、标签页、搜索页这些容易被频繁访问又变化较快的地址,要单独看一眼它们的缓存策略,别和文章页混在一起配置。

缓存键和 URL 参数容易被忽略

带追踪参数的分享链接、排序筛选参数,如果全部当作独立的缓存键,会在边缘留下大量内容几乎相同、只差几个字符的副本。这既占用存储,也让刷新变得麻烦。可以配置忽略不影响内容的参数,只保留真正决定页面内容的字段。同时确认站点没有把同一篇内容暴露成多个可缓存的地址,否则刷新时容易漏掉其中一部分。

更新内容后的刷新与验证流程

把刷新动作固定成流程,比每次凭感觉操作更稳:

  1. 先在源站直接确认内容已经改好,回源请求拿到的是新版本。
  2. 按具体 URL 精确刷新,而不是一上来就全量刷新。
  3. 如果改的是模板或公共区块,考虑目录级刷新。
  4. 刷新完成后预热几个主要入口页,避免第一批访客回源压力过大。
  5. 用无痕窗口或另一台设备再打开一次,排除本地浏览器缓存的干扰。

顺带检查几个容易漏的地址:XML sitemap、RSS 或 feed、栏目的第一页,以及之前被分享出去的老链接。这些地方往往挂在同一个域名下,却用了不同的缓存规则。

纳入日常巡检的几项

  • 发布重要更新后,确认目标页面的 Age 与内容版本一致。
  • 抽查首页、栏目页、文章页三类模板的响应头,确认设置没有被改回默认。
  • 确认静态资源更新后文件名或版本号确实变了。
  • 关注缓存命中率的变化,突然下降通常意味着参数或规则出了问题。
  • 记录每次全量刷新的时间和原因,便于事后对比流量与回源日志。

缓存本身是为了让站点更快,不是为了让人猜不透。把“改完内容、刷新、验证”这三步写进发布清单,多数“页面更新了但别人看到还是旧的”的问题,都能在几分钟内定位到是哪一层没跟上。