查看文档目录

缓存:状态头、不缓存的原因与刷新

节点缓存怎么判定命中:X-CDN-Cache 的取值、15 种不缓存的原因与处理办法、缓存键组成,以及刷新 URL、目录、整站和预热的生效方式与耗时。

工作原理

请求先经过安全检查(访问控制、WAF、CC),再由缓存模块决定:能缓存就查缓存,命中直接返回;不能缓存就直接回源,也不存。源站响应回来后,节点再按响应头决定存不存。

缓存键由这几部分组成:网站标识、网站缓存代数、整站刷新代数、域名(或网站主域名,取决于缓存设置)、端口、路径与查询参数。查询参数和请求头是否进缓存键由缓存规则决定(保留、忽略或只取部分参数;可按指定请求头区分版本)。所以同一个文件在不同端口、不同域名下是两份缓存。

状态头 X-CDN-Cache

网站开了缓存,且网站设置里的“响应头显示缓存状态”打开(默认打开)时,每个响应都带 X-CDN-Cache。网站处在攻击升级 B 级及以上时,主控自动关掉这两个头,避免攻击者据此判断缓存是否被击穿。

取值含义
HIT命中缓存,没有回源
MISS缓存里没有,回源取到并按规则存下
EXPIRED缓存已过期,回源取了新内容
STALE缓存已过期但源站出错,按规则返回了旧内容
UPDATING缓存已过期,正在后台更新,先返回旧内容
REVALIDATED缓存已过期,向源站确认内容没变后继续使用
BYPASS这次没有走缓存,原因见 X-CDN-Cache-Reason

不缓存的原因 X-CDN-Cache-Reason

请求侧的原因按下表顺序判断,命中第一条就停止。

原因什么时候出现怎么处理
method请求方法不是 GET 或 HEAD正常现象
authorization请求带 Authorization 头正常现象;登录后的个人内容不应进缓存
cookie请求带 Cookie,且没有任何缓存规则覆盖这个路径给静态资源路径加缓存规则;规则覆盖的请求会忽略请求 Cookie
upgradeWebSocket 等升级请求正常现象
search_engine网站开了“搜索引擎回源”,请求来自搜索引擎蜘蛛正常现象:蜘蛛走单独的源站,既不读也不写访客缓存
no_cache_rule没有缓存规则覆盖这个请求,或覆盖它的规则不缓存这个状态码检查缓存规则的路径、扩展名和状态码
no_cache_condition命中的规则里“不缓存条件”成立核对不缓存条件
key算不出缓存键:查询串超过 8 KiB 或 256 个参数、参与缓存键的请求头单个超过 4 KiB 或合计超过 16 KiB、百分号编码不合法、路径不以 / 开头缩短查询串,或在规则里忽略无关参数
purge_state节点刚启动,还没有加载各网站的刷新代数正常现象,节点加载完刷新代数后消失;这段时间不缓存,是为了不让已刷新的内容回来
disabled网站缓存已关闭在缓存设置里打开

响应侧的原因在源站回应后判断:

原因什么时候出现怎么处理
set_cookie源站响应带 Set-Cookie静态资源不要下发 Cookie
origin_no_store源站 Cache-Control 含 private、no-store 或 no-cache改源站的 Cache-Control 响应头
object_size响应大小不在缓存规则的最小、最大对象范围内调整规则的大小范围
content_type响应的 Content-Type 不在规则允许的类型里调整规则的内容类型
response_rule网站的响应规则替换了这次响应(如错误页)正常现象:被替换的响应不进缓存

刷新与预热

操作怎么生效耗时量级
刷新 URL节点按缓存键直接删掉这个文件通常立即完成。查询参数或请求头参与缓存键的网站,要扫描缓存文件,耗时同刷新目录
刷新目录(含通配域名)节点找出该网站所在缓存分区里路径匹配的文件并删除默认用缓存索引,30 万个文件的分区约几秒;索引在建或不可用时扫描整个分区,100 万个文件冷读约 3 分钟
刷新整站节点递增该网站的刷新代数,之后的请求立即不再命中旧内容;旧文件随后在后台删除对访客立即生效
预热每个节点各自向源站请求一次这些地址并存进缓存取决于源站速度和文件大小
  • 一次最多提交 500 个地址。URL 刷新、目录刷新、预热各有每日额度,按账户计(账户的所有成员和网站共用),按北京时间自然日计算;整站刷新算一次目录刷新。
  • 每个节点的刷新和预热任务排队串行执行,一个很慢的目录刷新会让后面的任务等它。任务最长执行 1 小时。
  • 提交时不指定节点,任务发给承载该网站的全部节点;24 小时内新开始承载这个网站的节点会自动补做同一任务。
  • 过期内容在磁盘上最多保留 24 小时,供“源站出错时返回旧内容”使用。

常见问题

一直是 MISS 或 BYPASS

先看 X-CDN-Cache-Reason。最常见的是 cookie(请求带 Cookie 且路径没有缓存规则)和 set_cookie、origin_no_store(源站不允许缓存)。如果是 MISS 而不是 BYPASS,可能是请求落在了不同节点:每个节点各有一份缓存,每个节点第一次都会回源。

刷新后还看到旧内容

确认刷新任务在每个节点都成功(操作记录里查看每个节点的结果)。浏览器自己也会缓存,换一个浏览器或带上不同的查询参数再试。

预热完了,访客仍然回源

预热只在提交时承载网站的节点上做。访客落到的节点如果不在其中,或者访客请求的缓存键不同(端口、域名、查询参数不一样),仍会回源一次。

能防止缓存投毒吗

只有缓存规则覆盖的 GET、HEAD 请求才会被存下,带 Authorization 或带 Set-Cookie 的响应都不缓存。不要让源站根据缓存键以外的请求头返回不同内容;需要按请求头区分时,把这个头加进缓存规则。