缓存是站点运营里性价比很高的一项优化:静态资源命中缓存,服务器压力小,访客打开也快。但缓存一旦配错,问题也很直接——内容早就改了,访客和蜘蛛拿到的还是几个小时甚至几天前的页面。等到发现列表页少了新文章、栏目页还挂着旧标题,往往已经过了一轮抓取。
缓存自查的目标不是把缓存关掉,而是让每一层缓存都清楚自己该存什么、存多久、什么时候失效。
一、先把缓存分层看清楚
排查之前,先确认站点上有哪几层缓存在起作用。很多“改了不生效”的问题,其实是找错了层。
- 浏览器缓存:由响应头控制,影响回访访客看到的版本。
- CDN 或反向代理缓存:位于访客与源站之间,缓存键决定哪些请求算同一个页面。
- 应用层页面缓存:CMS 或框架生成的静态化页面、片段缓存。
- 对象缓存与查询缓存:数据库、Redis 等,影响数据读取的新鲜度。
常见的误判是:后台已经更新,数据库也是新数据,但 CDN 上的 HTML 还没过期,前台看起来就是没变。
二、看响应头,别只看页面
用 curl -I 或浏览器开发者工具的 Network 面板,逐个确认关键地址的响应头。重点看这几项。
- Cache-Control:max-age 控制浏览器缓存时长,s-maxage 针对共享缓存,no-cache 表示可以存但每次要校验,no-store 表示完全不存。
- private 与 public:带登录态、购物车、个性化推荐的页面应标为 private,避免被公共缓存串给其他访客。
- ETag 与 Last-Modified:协商缓存的基础,缺失时每次访问都要重新回源。
- Vary:用于区分移动端与桌面端、压缩格式等维度,缺失时容易把一种版本返回给所有设备。
比较稳妥的做法是:HTML 用较短的 max-age 或协商缓存,带内容指纹的 CSS、JS、图片用一年期长缓存。指纹变了地址就变,不用担心旧文件被继续引用。
三、缓存键与刷新策略最容易出问题
缓存键决定了“什么算同一个页面”。这里有两个方向相反的坑。
- 缓存键包含太多参数,比如把广告追踪码、会话 ID 都算进去,命中率极低,等于没有缓存。
- 缓存键忽略必要参数,比如分页、筛选、语言版本,导致不同页面互相覆盖。
另外要确认私有内容没有被公共缓存,否则可能出现一位访客看到另一位访客信息的尴尬情况。发现后应先把相关路径排除在缓存之外,再排查缓存键规则。
缓存时长不是越短越安全。全站 no-store 会放大源站压力,抓取变慢,反而影响新内容被发现的速度。
四、发布后的刷新流程
内容更新后,只刷新必要的地址就够了,不必全站清缓存。可以按下面的顺序处理。
- 刷新被改动的详情页。
- 刷新对应的栏目页、列表页等聚合入口。
- 刷新首页中引用该内容的位置。
- 如需更新 sitemap,刷新 sitemap 地址本身。
- 确认刷新完成后再去看前台版本,避免在回源还没结束时反复刷新。
如果站点更新频繁,可以把刷新动作写进发布流程:先发布、再刷新关键 URL、最后抽查。这样比事后凭印象找问题更可靠。
五、别忽略回源与容量
缓存失效的瞬间,请求会集中涌向源站。如果源站在这一波回源里响应变慢,访客和蜘蛛都会感受到。可以关注几个信号:
- 缓存命中率是否稳定,是否在发布后出现明显下滑。
- 源站带宽与响应时间在回源高峰是否接近上限。
- 缓存刷新是否有节流,避免同一时间大批地址同时失效。
有条件的话,把刷新动作分散开,或利用 stale-while-revalidate 这类策略,让旧版本在后台更新的同时继续提供服务,减少源站尖峰。
六、一页自查清单
- 列出站点上的缓存层,确认每层由谁控制。
- 抽查首页、栏目页、详情页、静态资源的响应头。
- 确认登录态页面、个性化页面没有被公共缓存。
- 检查缓存键是否包含分页、语言、设备等必要维度。
- 确认发布后的刷新范围与执行人。
- 观察刷新后源站的响应时间与缓存命中率变化。
缓存策略没有一套通用答案,它取决于内容更新频率、访问量和源站承受能力。把上面几项检查做一遍,至少能避免“页面已经改了,访客和蜘蛛却还在看旧版本”这类本可避免的问题。