很多人对 CDN 的理解停留在“静态资源放上去就快了”。但在真实项目里,缓存策略设计得好不好,直接决定两件事:源站压力,以及用户看到的内容是否新鲜。
一、缓存什么:按“可变性”分层
先把资源分成四层,每层策略不同:
| 类型 | 例子 | 建议 |
|---|---|---|
| 永不变化 | 带哈希的 JS/CSS、字体 | 长缓存 + immutable |
| 很少变化 | 图片、主题静态文件 | 中长缓存 + 版本号 |
| 会变化但可旧 | 列表页 HTML | 短缓存 + stale-while-revalidate |
| 不可旧 | 后台、订单、个人信息 | 不缓存 |
关键是不要让“会变的”和“不变的”共用一个 URL。给静态资源加内容哈希或版本查询参数,是让长缓存安全的前提。
二、缓存多久:TTL 与“可接受的旧”
TTL 不该拍脑袋,而应该由业务回答一个问题:这份内容旧 10 秒,会不会造成损失?
- 首页列表旧 30 秒,通常没问题
- 文章详情页旧 5 分钟,通常没问题
- 库存、价格、权限,一秒都不能旧
stale-while-revalidate 很适合“可旧”的内容:先给用户旧副本,同时在后台刷新。用户不用等,源站也不用承受同步压力。
三、怎么失效:三种手段的取舍
- 版本化 URL:最可靠。新版本换 URL,旧缓存自然淘汰,无需 purge
- 主动 purge:快,但有传播延迟,且批量 purge 往往有限额
- 短 TTL:最简单,代价是回源频率上升
实践中常常组合使用:静态资源靠版本化,HTML 靠短 TTL + purge,接口靠不缓存或极短缓存。
四、怎么验证:别靠“我刷新看看”
“我这边好了”不是验证。至少要做三件事:
- 看响应头:
Cache-Control、Age、X-Cache是否符合预期 - 从不同地区/不同网络请求,确认边缘节点行为一致
- 观察回源率与 5xx,确认没有回源风暴
一个常见事故是:缓存刚上线,源站被打满。原因往往是没有做请求合并(同一资源并发回源只放一个请求过去),或者 TTL 太短导致缓存几乎不生效。
五、几个容易忽略的细节
Vary用多了等于自废缓存(比如按 User-Agent 全量区分)- 带 Cookie 的请求默认应绕过缓存,除非明确处理
- 压缩与缓存要一起考虑:缓存压缩后的表示能省带宽
- 404 也能缓存,但要短,否则“刚发布的新文章”会被 404 缓存挡住
结语
缓存策略的本质是用“允许的旧”换“更低的延迟和更小的源站压力”。把它当成一个业务问题,而不是一个配置项,答案会清楚很多。
评论 (0)