用户登录

技术文章

外部链接将在新标签页打开。

HTTP 缓存与 CDN 加速实践:从可缓存性判定到边缘验证

一句话回答

缓存与 CDN 加速的先后顺序是:先判定响应能否被复用、由谁复用、复用多久、何时必须校验,再讨论边缘节点部署。本文把这条链路拆成可判定的字段与验证步骤,并说明哪些结论需要实测、哪些属于规范定义而非厂商承诺。

缓存和 CDN 加速要解决的问题,首先要分清“这段响应能不能被重复使用”,其次才是“复用得多快”。如果缓存键、新鲜期和校验条件没有写清,边缘节点只会把错误的响应更快地发给更多人。需要先说明:本次写作没有可用的正文素材,因此下文只讨论 HTTP 缓存规范层面可判定的概念与验证方法,不引用任何 CDN 厂商的具体行为、版本差异或性能数字;凡涉及具体产品表现的,一律标为待核实。

一、把“复用条件”拆成四个问题#

按 HTTP 缓存规范(RFC 9111)的定义,一个响应是否被复用,取决于四件事。本文未附规范原文链接,具体条款请以 RFC 9111 为准。

  • 谁可以存:public 表示共享缓存(如 CDN)也可保存;private 表示只允许浏览器这类私有缓存保存;no-store 表示不得存储。
  • 存多久:max-age 面向私有缓存,s-maxage 面向共享缓存。两者同时出现时,共享缓存应优先采用 s-maxage。
  • 用前是否校验:no-cache 不是“不缓存”,而是“每次使用前必须先向源站校验”;must-revalidate 约束的是过期之后的复用行为。校验通常靠 ETag 与 If-None-Match 完成,命中时源站返回 304。
  • 不同请求能否共用同一份:Vary 声明哪些请求头参与缓存键,例如按 Accept-Encoding 区分压缩与非压缩版本。缺少 Vary 时,内容协商就可能把一份响应错发给另一类客户端。

二、CDN 是共享缓存,指令要分开写#

CDN 节点属于共享缓存,因此只写 max-age 并不能表达“边缘可以缓存多久”。把 s-maxage 单独写出来,才能让浏览器与边缘各自按不同时长工作。带 Authorization 或 Cookie 的响应在规范下的默认可共享性受限,是否放行取决于 public 等指令与 CDN 自身配置;具体实现差异需要以所用 CDN 文档为准,本文无法核实。

三、可执行的判定顺序#

  1. 先给资源分类:静态不变资源、按版本命名可长期缓存的资源、频繁变化但可短时复用的接口响应、绝不能存储的响应。
  2. 为每一类写下 Cache-Control 与是否需要 ETag,再决定是否加 Vary。
  3. 检查缓存键是否包含所有影响响应内容的维度(路径、查询参数、参与协商的请求头)。
  4. 在响应日志中记录缓存命中状态与 Age 等字段,确认边缘确实按预期复用。具体头名与日志字段因 CDN 而异,待核实。
  5. 修改缓存策略后,用同一组请求复测,比较命中与回源的比例变化,而不是只看单次响应。

四、响应头骨架(示意,未执行)#

下面的组合仅用于说明字段分工,未在任何服务器或 CDN 上执行,数值也不是推荐值,需按资源实际更新频率确定。

Cache-Control: public, max-age=60, s-maxage=600, must-revalidate
ETag: "v1-example"
Vary: Accept-Encoding

五、验证方式与边界#

可以用响应头观察来验证,下面的命令是演示写法,域名使用 example.com 占位,未实际执行:

curl -sI https://example.com/static/app.js

重点看三处:Cache-Control 是否与设计一致;Age 是否在增长(增长说明命中了共享缓存);带 If-None-Match 重发时是否返回 304。需要提醒的边界是:Vary: * 会使响应实际上无法被复用;把用户相关的响应标成 public 会造成跨用户串号;缓存时长与业务更新频率不一致时,问题往往表现为“改了没生效”,而不是报错。

哪些必须实测#

规范只定义语义,不保证任何 CDN 的实际行为。以下事项只能通过实际请求确认,本文标为待核实:边缘节点的默认缓存时长与忽略规则、查询参数是否参与缓存键、清除缓存的生效时间、以及压缩与协商的具体处理。上线前建议为每类资源保留一条可复现的验证请求,并记录响应头快照作为证据。

本文为 API.PLUS 开发者内容整理,未涉及任何具体接口端点,也未对任何在线服务发起调用。

作者:沐小悠

本文约 5 分钟读完 · 关键词:HTTP 缓存、CDN 加速、Cache-Control、ETag、Vary

更多文章 GET 示例接口

「」标签下的其他文章