用户登录

技术文章

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

CDN 缓存命中率低时先查什么:缓存键、新鲜度与验证的排查顺序

一句话回答

文章按“先分清私有缓存与共享缓存,再看缓存键是否碎片化,最后看新鲜度与再验证”的顺序,说明 CDN 命中率偏低时的排查路径,并列出不应缓存的响应类型;具体 CDN 厂商的默认值、响应头名称与刷新接口未在材料中给出,标注待核实。

CDN 命中率低,通常不是“CDN 没生效”这一句话能解释的。可按三层定位:先把浏览器私有缓存与 CDN 共享缓存分开看,再检查缓存键是否被请求头或查询串拆碎,最后确认新鲜度与再验证策略是否让边缘节点每次都回源。本文只讨论 HTTP 缓存规范的通用语义,不涉及具体 CDN 厂商的控制台选项、默认 TTL 与刷新接口——这些需查各家文档,本次材料未提供。

第一层:私有缓存与共享缓存不是一回事#

HTTP 缓存规范(RFC 9111)把缓存分为私有缓存(通常是浏览器)和共享缓存(CDN 边缘、反向代理)。两个指令常被混用:max-age 对两者都生效,而 s-maxage 只约束共享缓存,并会覆盖 max-age。如果源站只设置了较短的 max-age 而没有 s-maxage,边缘节点就会按短值过期,回源频率随之上升。这是规范语义,不是某家厂商的行为。

第二层:缓存键决定“能不能命中”#

缓存键至少包含主机与路径,是否包含查询串、包含哪些请求头,取决于 CDN 配置。键一旦被拆细,相同内容会被存成多份,命中率自然下降。常见来源有三类:

  • Vary 列了粒度很细的请求头。例如 Vary: User-Agent 会让每个 UA 版本各存一份。Vary: Accept-Encoding 一般必要,因为它对应不同的压缩表示。
  • 查询参数顺序或无关参数不同,例如带追踪参数的链接。建议在边缘侧做参数白名单或重排。
  • 响应携带 Set-Cookie 或请求带 Authorization 时,许多实现默认不缓存或按用户区分。具体规则依实现而定,待核实。

第三层:新鲜度与再验证#

新鲜度由 Cache-Control 的时长类指令给出;过期后,缓存可用 ETag 或 Last-Modified 发起条件请求,源站返回 304 即可复用旧内容、只更新元数据。这意味着:即使 TTL 很短,只要 304 比例高,回源带宽仍然可控;但回源请求次数不会因此减少,而命中率统计口径通常按“未回源”计算,两者不要混看。

下面是一组说明用的响应头示意,未实际执行,也不代表任何厂商的默认行为,仅用于展示字段组合:

HTTP/1.1 200 OK
Cache-Control: public, max-age=60, s-maxage=600
ETag: "demo-v1"
Vary: Accept-Encoding
Content-Type: application/json

占位值仅为演示:max-age 让浏览器 60 秒内复用,s-maxage 让共享缓存保留 600 秒。真实取值应依据内容变更频率确定。

一条可执行的排查顺序#

  1. 抓一次源站直连响应,确认是否带 Cache-Control,且不是 private 或 no-store。
  2. 经 CDN 再抓一次,比对响应头是否被改写;Age 是否递增可作参考,但用于标识命中/回源的专有响应头名称因厂商而异,待核实。
  3. 检查缓存键:Vary 列表、查询串是否规范化、是否存在按 Cookie 或 UA 分桶。
  4. 确认没有因 Set-Cookie、鉴权头或个性化内容而被动绕过缓存。
  5. 最后才调整 TTL:先让内容可缓存,再谈缓存多久。

边界:哪些响应不该进共享缓存#

含用户身份或权限差异的内容、带会话 Cookie 的响应、以及需要逐请求计费或审计的接口,不应放入共享缓存。反过来,静态资源与公开只读接口是收益最大的部分。同理,stale-while-revalidate 之类扩展指令的支持范围取决于客户端与 CDN 实现,启用前需自行核对,本文不给兼容性结论。

需要注意的是,命中率的统计口径(是否计入 304、是否排除预检请求)、各厂商的默认 TTL 上限与刷新 API 的行为,本次材料均未提供,属于需要使用方按所用平台文档核实的内容;在核清口径之前,不同报表之间的命中率不宜直接比较。

作者:沐小悠

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

更多文章 GET 示例接口

「」标签下的其他文章