内容改完、后台点了发布,前台看着还是旧样子;或者反过来,缓存过期设得太短,每隔几分钟就有一批请求打回源站,带宽和数据库连接跟着起波动。这两类现象看起来相反,根子都在同一件事上:缓存策略没理清。
先分清三层缓存各由谁管
- 浏览器本地缓存:由响应头里的 Cache-Control、Expires 决定,用户自己或清理工具能清掉,站点很难强制失效。
- CDN 边缘节点缓存:由 CDN 的缓存规则和缓存键决定,刷新按钮作用于这一层。
- 源站与应用层缓存:页面缓存、对象缓存、OPcache、反向代理缓存,通常由运维配置和程序逻辑控制。
排查时先确认问题出在哪一层,不然容易出现「刷了 CDN 还是旧的」「清了浏览器还是旧的」这种来回折腾。
几个值得警觉的信号
- 同一个 URL 在不同地区、不同网络下拿到的内容版本不一致。
- 后台显示已发布,前台、接口、搜索预览三处看到的内容对不上。
- 源站带宽曲线呈现规律性尖峰,间隔与缓存时间接近。
- 带查询参数的 URL 命中率明显低于不带参数的版本。
- 登录后的页面偶尔出现别人的信息,或未登录也能看到登录态内容。
排查顺序建议
- 用命令行或浏览器开发者工具看响应头,重点看 Age、Cache-Control、ETag、Last-Modified 以及 CDN 自己加的命中标识。
- 换节点、换地区、换设备各访问一次,确认是全局问题还是局部节点问题。
- 看 CDN 后台的缓存命中率与回源率,判断是缓存没生效,还是反而缓存过久。
- 检查缓存键规则:是否忽略查询参数、是否按 Cookie 或请求头区分,是否把无意义参数也算进键里。
- 检查源站是否给动态页面配了过长的缓存时间,或者把登录态页面当公共资源缓存。
- 确认刷新操作的范围:单条 URL 刷新、目录刷新还是全站刷新,是否覆盖了带参数的版本。
常见配置误区
- HTML 文档设了很长的 max-age,结果每次更新都要等用户缓存自然过期。
- 缓存键里混入追踪参数,同一篇内容在边缘节点存了十几份副本。
- Vary 头设置不当,导致本该复用的缓存被拆散,或者该区分的没区分。
- 301、302 跳转被长时间缓存,改完跳转目标后旧规则还在生效。
- 刷新只处理了主 URL,带参数、带斜杠变体的地址仍指向旧内容。
建议把「改内容、发布、刷新、验证」写成一个固定清单,每次更新照着走一遍,比事后猜哪里没生效要省时间。
验证环节别省
刷新之后至少做三件事:用无痕窗口访问主 URL,用带参数的地址再访问一次,再挑一个远端节点确认。如果站点有接口或小工具,也顺手拉一次,避免页面更新了、数据接口还是旧缓存。
回源压力同样要盯
缓存时间不是越短越安全。对更新不频繁的静态资源,可以给较长缓存并配合文件名版本号;对经常变动的列表页和首页,可以用较短的边缘缓存加主动刷新。真正的目标不是「永远最新」,而是更新能被及时看到、回源请求又不会把源站压垮。
把三层缓存的分工、缓存键规则和刷新流程记在一份文档里,值班的人换了一茬也能照着查,站点运营的稳定性往往就体现在这些看起来不起眼的配置上。