HTTP 缓存与 CDN 加速:缓存键、条件请求与失效顺序的排查清单
一句话回答
缓存效果取决于四件事:谁能存、存多久、按什么键存、怎么失效,这些都写在响应头里;CDN 只是按声明执行。排查应从缓存键与 Vary 入手,再看 s-maxage 与失效是否生效;304 只省带宽不省源站计算。具体 CDN 产品对指令与失效语义的支持需以该产品文档为准。
HTTP 缓存与 CDN 加速真正要解决的问题,可以拆成四件事:谁能存、存多久、按什么键存、怎么让它失效。这四件事都在响应头里表达,CDN 只是按这些声明执行。协议语义由 RFC 9111(HTTP Caching)定义;某个具体 CDN 产品支持哪些指令、控制台如何配置、失效传播需要多久,本文不作结论,需以该产品文档为准,属于待核实项。
三条响应头决定缓存行为#
- Cache-Control:
public允许共享缓存(含 CDN 边缘节点)存储;private只允许浏览器这类私有缓存;no-store不落盘。共享缓存与浏览器的时长可以分开表达:s-maxage面向 CDN,max-age面向浏览器。 - 验证器:
ETag或Last-Modified让缓存过期后能用条件请求(If-None-Match/If-Modified-Since)换回 304,省掉的是响应体,不是往返。 - Vary:声明响应随哪些请求头变化。
Vary: Accept-Encoding是常规做法;把Authorization、Cookie这类高基数字段写进去,缓存键几乎唯一,命中率会明显下降。
缓存键才是命中率的决定因素#
CDN 的默认缓存键通常由「主机名 + 路径 + 查询串」构成,Vary 指定的请求头再叠加进去。由此产生两个常见后果:
- 查询串参与键:带时间戳、跟踪参数等随机值的请求几乎无法命中,需要在边缘侧规范化路径或忽略无关参数。是否可配置取决于具体 CDN,待核实。
- 鉴权内容混进共享缓存:如果同一路径既有
public响应,又可能返回带用户身份的内容,就存在把 A 用户数据发给 B 用户的风险。这类端点应标private,或拆成「公开元数据」与「按用户数据」两个端点。
示例:一份可读的缓存声明#
以下为格式示例,未执行,也不代表任何服务的真实响应:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: public, max-age=60, s-maxage=300
ETag: "v1-abc"
Vary: Accept-Encoding
读法:浏览器最多复用 60 秒,CDN 最多 300 秒;过期后携带 ETag 回源验证,内容未变则返回 304。
三个症状,对应三条排查路径#
- 命中率低:先看缓存键——查询串、
Vary、Cookie 是否参与;再看Cache-Control是否被中间层改写或降级。 - 内容陈旧:区分是浏览器缓存还是边缘缓存。浏览器侧看
max-age,边缘侧看s-maxage与失效(purge)是否真的下发;失效的语义与生效时间因厂商而异,待核实。 - 源站压力没降:304 只省带宽、不省计算。若源站仍在每次生成完整响应,通常是验证器没生效,或响应头在链路中被改写。
边界#
缓存是否有效,本质是「声明」与「执行」是否匹配的问题。声明写错,CDN 只会更快地把错误放大;声明写对,边缘是否支持该指令仍需逐项确认。涉及 API.PLUS 平台的具体缓存配置项与默认行为,本次材料未提供,需查阅其官方文档核实。