站点运营

站点运营: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,通常是比较稳妥的做法。同时也要清楚,刷新缓存只保证蜘蛛拿到的是最新版本,至于什么时候来抓,仍由搜索引擎自己决定。