缓存排障指南

更新时间:
复制 MD 格式

本文按症状汇总 CDN 缓存场景的排障方法:缓存不生效与未命中、缓存命中率低与回源率高、响应头与跨域异常、视频与大文件异常、内容不更新与访问异常。

通用排查前置步骤

说明

本文适用于阿里云 CDN,且加速域名已完成接入、CNAME 解析已生效。若使用全站加速(DCDN),部分配置入口和功能名称可能不同,请以控制台实际显示为准。

以下确认项在多数缓存问题中都会用到,建议开始排查前先逐项完成,避免因环境干扰得出错误结论:

确认项

说明

确认 CNAME 解析正确

执行 dig 加速域名,确认最终解析到 CDN 分配的 CNAME,且没有残留指向源站的 A/AAAA 记录。

确认配置已全网生效

控制台中规则状态需为成功,配置下发到全网节点通常需要 3~5 分钟。

排除浏览器本地缓存

使用无痕模式或 curl 测试,避免浏览器缓存干扰判断。

清除 CDN 存量缓存

新配置只对配置生效后的新请求生效,已按旧策略缓存的资源需通过刷新预热提交 URL 刷新或目录刷新。

说明

本文多处将「缓存过期时间设为 0 秒」作为兜底手段。过期时间为 0 意味着每次请求都回源,会显著增加源站负载并降低加速效果,仅建议对确实需要实时性的动态内容(如 API 接口)使用,不要对静态资源全局配置。

如何判断缓存是否命中

排查缓存问题前,先通过响应头确认资源的缓存状态:

  • 用 GET 请求查看响应头:执行 curl -v -o /dev/null "http(s)://加速域名/资源路径"curl -I(HEAD 请求)在部分场景可能不触发节点对资源体的真实缓存逻辑,导致误判为未命中,建议优先使用 GET 请求验证。

  • 看 X-Cache 判断命中状态HIT 表示命中缓存;MISS 或该字段不存在表示未命中,本次请求已回源。

  • 看 Age 与 X-Swift-CacheTime 判断剩余缓存时间Age 是资源已在节点缓存的秒数,需与 X-Cache 一起判断——X-Cache 为 MISS 且 Age 为 0 表示本次请求已回源;X-Cache 为 HIT 但 Age 为 0,表示资源刚被缓存不到 1 秒。X-Swift-CacheTime 是允许缓存的总时长,剩余时间 = X-Swift-CacheTime − Age。

  • 确认请求是否经过 CDN:若响应头 Server 为源站标识(如 AliyunOSSnginx)且没有 X-Cache、X-Swift-CacheTime 等 CDN 响应头,说明请求未经过 CDN 节点而是直连了源站。请用 dig 加速域名nslookup 加速域名 确认最终解析结果,只保留 CDN 分配的 CNAME 记录,删除指向源站 IP 的 A/AAAA 记录或指向源站域名的 CNAME 记录。

缓存不生效与未命中类

配置缓存规则后仍然回源或未命中缓存?

排查步骤:

  1. 确认配置已生效:新增或修改缓存规则后,规则状态会显示配置中,表示配置正在下发到全网节点,通常几分钟内变为成功。配置未生效期间不要急于验证。

  2. 确认新规则已对目标资源生效:新规则只对新请求生效,已缓存在节点上的资源仍按旧策略提供服务直至过期。如需立即生效,请先执行刷新预热清除旧缓存。

  3. 检查规则匹配优先级:请求同时命中多条规则时只有一条生效,默认权重高者优先;权重相同时通常创建时间晚的规则优先(以控制台实际说明为准)。请确认目标路径命中的规则权重最高,例如具体目录(/static/)的权重应高于根目录(/)的规则。

  4. 检查源站响应头是否禁止缓存:若源站返回 Cache-Control: no-cacheno-storemax-age=0Pragma: no-cache,CDN 默认遵循源站指令,不同指令对回源行为的影响见下方表格。可在缓存规则中开启忽略源站不缓存标头强制按控制台规则缓存,或调整源站配置,对静态资源去掉不缓存指令。

  5. 检查 URL 参数处理方式:若 URL 带参数且未开启忽略参数,不同参数的 URL 会被视为不同资源,导致命中率下降。可开启忽略参数保留指定参数

  6. 检查是否误配置了根目录不缓存:若根目录 / 的规则权重最高且过期时间为 0 秒,所有请求都会回源。

上述第 4 步中,不同的源站不缓存指令对回源行为的影响差异较大,请根据实际指令判断源站压力:

源站响应头

CDN 行为

对源站的影响

Cache-Control: no-store

完全禁止缓存,每次请求都完整回源拉取资源。

源站承担全部流量压力。

Cache-Control: no-cachemax-age=0

允许节点存储缓存副本,但每次使用前必须回源验证。验证通过时源站返回 304(不含响应体),开销远小于完整回源。

回源次数不减,但每次仅产生一个小体积的条件回源,带宽压力可控。

Pragma: no-cache

HTTP/1.0 兼容指令,效果类似 no-cache

同上。

缓存过期时间已设为 0,但访问到的仍不是最新内容?

过期时间设为 0 的目的是每次请求都回源获取最新内容。若仍返回旧内容,排查步骤:

  1. 排除浏览器本地缓存:清除浏览器缓存或使用无痕模式重新测试,确认是节点返回旧内容而非浏览器缓存。

  2. 清除配置修改前的存量缓存:修改配置前已缓存的资源不会自动清除,需通过刷新预热提交 URL 刷新。

  3. 检查源站自身是否有缓存:源站服务器(如 Nginx 缓存、应用层缓存)可能返回旧内容,CDN 回源拿到的就是旧数据。

  4. 确认配置已全网生效:规则状态需为成功,配置下发到全部节点需要几分钟。

  5. 确认请求命中了预期节点:不同运营商、不同地区的用户可能命中不同节点。可在多个地区分别测试,或结合 CDN 实时日志、响应中的节点 IP 进一步定位。

配置自定义 Cache Key 区分移动端和 PC 端后没有生效?

  1. 检查配置完整性:自定义 Cache Key 通常需要按请求特征(如 User-Agent)设置规则条件,再分别添加不同的 Cache Key 变量。请确认已正确识别移动端和 PC 端的请求特征,且两条规则的匹配条件不会互相覆盖。

  2. 等待生效:配置提交后需等待 5~10 分钟全网同步。

  3. 刷新旧缓存:配置修改前已按旧 Cache Key 缓存的资源不会自动失效,需提交刷新(建议使用目录刷新)。

  4. 客户端验证:清除浏览器缓存后重试,检查响应头中的 X-Cache 是否为 MISS

  5. 使用真实终端测试:使用不同终端的真实 User-Agent 发起请求,而非仅切换浏览器窗口尺寸(浏览器模拟的 UA 可能与真实设备不同)。

说明

自定义Cache Key忽略参数存在冲突:两者同时配置时,忽略参数功能将失效。若已使用自定义 Cache Key,请在其中配置请求参数处理策略而非另外开启忽略参数。

因响应包含 Set-Cookie 导致缓存命中率为 0 如何解决?

问题原因:当源站响应中包含 Set-Cookie 响应头时,CDN 默认不会缓存该响应,导致缓存命中率为 0。

重要

删除 Set-Cookie 是高风险操作。该响应头承载用户登录态维持、会话鉴权、行为埋点等关键业务逻辑,全局删除可能导致用户登录失效、购物车丢失、鉴权异常。请先评估影响范围再操作。

推荐方案(按优先级):

  • 源站侧治理(推荐):让源站对静态资源(图片、CSS、JS、字体等)停止返回 Set-Cookie。这是根本解决方案,既不影响动态接口的会话管理,又能提升缓存命中率。

  • CDN 侧按路径删除:若源站无法调整,可在 CDN 侧仅对静态资源路径(如 /static/*.css*.js)删除该响应头,避免影响动态接口。

CDN 侧按路径删除的操作步骤:

  1. 登录 CDN 控制台,在域名管理中找到目标域名,单击管理

  2. 在域名详情页左侧导航栏中,单击回源配置,进入修改入站响应头页签。

  3. 单击添加,将规则条件限定在静态资源路径,响应头操作选择删除,响应头名称填写 Set-Cookie

  4. 配置完成后,通过刷新预热清除已缓存的旧响应,使新规则生效。

如果配置后缓存命中率仍未提升,请检查:缓存规则中是否已开启忽略源站不缓存标头;是否开启了忽略参数,避免同一资源因查询参数不同而被拆分为多个缓存对象。CDN 默认缓存规则请参见配置CDN缓存过期时间

缓存命中率低与回源率高类

缓存命中率低、回源率高或源站带宽跑满?

命中率过低意味着大部分请求都要回源,公网链路不稳定会让加速效果变差,同时给源站带来负载压力。排查步骤:

  1. 检查源站是否返回不缓存指令:这是命中率低和源站带宽跑满最常见的原因。若源站返回 Cache-Control: no-cacheno-storemax-age=0Pragma: no-cache,CDN 会遵循源站指令不缓存,每次请求均回源。可在缓存过期时间配置中开启忽略源站不缓存标头强制按控制台规则缓存,或调整源站配置。

  2. 检查缓存规则是否误配置:确认根目录 / 的缓存过期时间未被配置为 0 秒且权重最高,否则所有请求都会回源。

  3. 检查 URL 是否带可变参数:URL 中问号后的参数变化会让同一份内容被视为不同资源。开启忽略参数后可将这类请求合并为同一缓存对象,详见下一条。

  4. 区分动静资源分别配置:为静态资源(图片、CSS、JS、字体等)设置较长缓存时间(如 30 天),为动态内容(如 PHP、JSP、API 接口)设置过期时间 0 秒。

  5. 大文件场景开启 Range 回源:对视频、安装包等大文件确保已开启 Range 回源,避免每次请求都回源获取完整文件。开启前请确认源站支持 Range 请求(即能够返回 206 Partial Content),源站不支持时开启该功能可能导致请求失败或返回异常内容。

  6. 检查业务 QPS 是否过低:节点磁盘空间有限,访问频率低的资源会被热点资源汰换掉从而造成回源。QPS 只有十几的域名建议通过刷新预热提交预热任务,保证资源常驻节点。

页面主请求 X-Cache 始终为 MISS 导致缓存命中率低如何解决?

问题现象:页面整体命中率很低,检查响应头发现主请求的 X-CacheMISS,但页面内单个文件的 URL 响应头为 HIT

问题原因:URL 中携带了随请求变化的参数(如时间戳),未开启忽略参数功能时,CDN 将每个参数不同的 URL 视为独立资源,无法复用缓存。例如 http://example.com/movie/res/ArrowScene.ccbi?_t=1699999999?_t= 后的数值每次都不同。

解决方法:在 CDN 控制台开启忽略参数功能,开启后参数部分不参与缓存对象的计算,同一资源的不同参数请求会命中同一份缓存。若业务确实依赖部分参数,可选择保留指定参数,仅忽略无关参数。

缓存命中率突然下降可能是什么原因?

命中率短期波动或持续下降,常见原因如下:

  • 执行过刷新缓存操作:手动或自动刷新会清除节点缓存,短时间内命中率下降属正常现象,随着资源重新缓存通常在数小时内自动回升。

  • 带宽突增:短时间内流量大幅上涨会带来大量首次请求,回源增多导致命中率下降。

  • 大量访问新内容:节点频繁请求首次访问的新资源时必然回源,表现为命中率走低。

  • 调整过缓存规则:修改缓存策略(尤其是缩短过期时间)会影响命中率。

  • URL 带可变参数:参数变化使同一内容被拆成多个缓存对象。

  • 缓存过期时间设置不合理:未按资源更新频率区分配置,导致缓存过早失效。

响应头与跨域异常类

已配置 Access-Control-Allow-Origin 但访问仍提示跨域?

已在 CDN 配置跨域响应头,但客户端仍报跨域错误且响应头中看不到该字段,可能原因与处理方法如下:

  • 配置未生效:确认配置已保存且规则状态为成功

  • 配置尚未下发完成:出站响应头配置修改后一般在 5 分钟内生效,请等待后重试。该配置只影响客户端收到的响应,不影响节点的缓存行为,因此无需刷新或重新预热(预热不会改变已缓存资源的响应头)。

  • 源站响应头与 CDN 配置冲突:源站也返回了跨域响应头时可能相互覆盖。建议统一源站和 CDN 的跨域配置,或在修改出站响应头中将是否允许重复设为不允许,使 CDN 配置的值覆盖源站返回的值。

  • 浏览器缓存了旧响应:清除浏览器缓存或使用无痕模式测试。

  • 泛域名配置方式不支持:开启跨域验证后仅支持配置单个泛域名,或将多个精确域名用逗号分隔,不支持用逗号分隔多个泛域名。

  • Access-Control-Allow-Origin 值与请求 Origin 不一致:浏览器报错 "The 'Access-Control-Allow-Origin' header has a value that is not equal to the supplied origin" 时,说明返回的允许源与实际请求源不匹配。可通过以下方式解决:

    • 修改出站响应头中重新配置 Access-Control-Allow-Origin是否允许重复选择不允许,使新值覆盖源站返回的旧值。

    • 业务允许时,可将该响应头配置为动态返回请求中的 Origin 值,使允许源始终与请求源一致。配置完成后等待约 5 分钟生效即可,无需刷新缓存。

跨域资源共享的配置方法请参见配置跨域资源共享

配置自定义响应头后未生效?

  • 确认请求经过了 CDN 节点:检查域名 DNS 解析是否只保留 CDN 的 CNAME 记录,删除了 OSS 等源站的直接解析记录。流量直连源站时,CDN 配置的响应头不会生效。

  • 确认配置的是出站而非入站响应头:入站响应头仅作用于源站到 CDN 节点之间的通信,终端用户不会感知。如需影响终端用户收到的响应,请配置修改出站响应头

  • 确认源站是否返回了该响应头:CDN 默认透传源站响应头,源站未返回时 CDN 也不会返回。若希望无论源站是否返回都强制携带该响应头,请在修改出站响应头中选择添加操作。

  • Content-Type 未生效时检查源站元数据:若源站(如 OSS)在上传文件时未指定正确的 Content-Type,回源获取的元数据会与预期不符。请检查源站上传文件时的 Content-Type 设置。

  • 确认已等待配置生效:出站响应头配置修改后一般在 5 分钟内生效,且仅影响客户端收到的响应、不影响节点的缓存行为,因此无需刷新或重新预热(预热不会改变已缓存资源的响应头)。

出站响应头的配置方法与参数说明,请参见修改出站响应头

CDN 加速后的页面出现乱码如何处理?

问题原因:源站返回的 Content-Type 响应头未正确指定字符编码,客户端按错误编码解析内容导致页面乱码。

方案一(推荐,从源头修复):修改源站配置,确保返回 HTML 时 Content-Type 包含正确的字符编码声明。

方案二(在 CDN 侧改写):

  1. 登录 CDN 控制台,在域名管理中找到目标域名,单击管理

  2. 修改入站响应头中添加规则,将匹配路径下的 Content-Type 改写为 text/html; charset=utf-8

  3. 配置完成后,通过刷新预热刷新该路径下的缓存资源,使节点按正确的类型重新缓存。

说明

使用入站响应头改写 Content-Type 是在回源阶段修正类型,节点会以正确类型重新缓存资源;若使用出站响应头,节点缓存的仍是错误类型,仅在输出时覆盖,不够彻底。另外,入站响应头不支持对泛域名配置。

配置响应头控制视频下载或预览不生效怎么办?

可通过修改出站响应头功能配置 Content-Disposition 响应头来控制视频的下载或预览行为:设置为 attachment; filename='video.mp4' 时,用户访问该资源将触发下载;设置为 inline 时,资源将在浏览器中直接预览。

如果配置不生效,请检查以下事项:

  1. 规则引擎匹配条件:确保规则的匹配条件针对的是 URI 路径(如包含 /video-origin/20260414),而非仅匹配查询参数(query string)。规则引擎通过识别用户请求中的路径信息来决定配置是否生效。

  2. 节点已缓存旧响应头Content-Disposition 直接影响浏览器行为,若配置后 5 分钟仍未生效,请先排除浏览器本地缓存(使用无痕模式重试),并确认规则状态为成功

JS 文件被当成 text/html 错误处理如何解决?

问题原因:源站首次返回 JS 文件时,Content-Type 响应头被错误设置为 text/html。CDN 将该错误类型缓存后,浏览器按 text/html 解析 JS 文件,导致乱码或执行异常;第二次访问时,由于源站已修正 Content-Type 或 CDN 重新回源获取了正确类型,页面恢复正常。

解决方法:

  1. 在 CDN 控制台的修改入站响应头中添加规则,匹配 JS 文件路径(如 *.js),将 Content-Type 强制替换为 application/javascript

  2. 配置完成后,通过刷新预热刷新该 JS 文件的缓存,使新规则立即生效。

说明

本问题与页面乱码的根因相同(源站返回了错误的 Content-Type),均推荐优先修复源站配置,源站无法调整时再通过入站响应头改写。

视频与大文件异常类

视频播放出现 ERR_CONTENT_LENGTH_MISMATCH ?

问题原因:节点上缓存的文件长度与源站实际内容不一致,或源站返回了异常的 Content-Length 响应头。最常见于源站更新了视频文件但 CDN 仍返回旧版本缓存。

解决方法:

  • 刷新预热页面提交该视频 URL 的刷新任务,清除节点上的旧缓存。

  • 若源站为 OSS,可在 OSS 控制台开启CDN 缓存自动刷新功能,源站文件更新后自动触发 CDN 缓存刷新。

  • 检查源站稳定性,确保不会间歇性返回异常的 Content-Length,可通过多次使用 curl -I 直连源站对比验证。

日志中出现大量 206 状态码或多次回源是否正常?

正常。视频播放器和下载工具通常使用 Range 请求分段加载资源,每次只请求部分内容,服务端返回 206 Partial Content。即使命中 CDN 缓存,返回的也是 206 状态码,不属于异常。

费用说明:只要客户端向 CDN 发起请求并接收数据,无论是否命中缓存,均计入 CDN 流出流量费用。

优化建议:确保已开启 Range 回源,使节点能按需从源站拉取分片并缓存,提高后续分段请求的命中率;同时在源站配置合理的 Cache-Control(如 max-age=86400),利用浏览器本地缓存减少重复请求。

内容与访问异常类

静态资源已命中缓存,但首页仍然加载很慢?

问题原因:图片、CSS、JS 等静态资源已命中缓存并正常加速,但首页(根路径 /)通常没有配置缓存规则,每次访问都要回源获取,加载速度完全取决于源站处理耗时。

解决方法:为加速域名添加根目录的缓存过期时间规则,让首页内容也被节点缓存:

重要

以下方案仅适用于纯静态或伪静态首页(如官网、博客)。若首页包含登录态、个性化推荐等与用户相关的动态内容,缓存根目录可能导致用户看到其他人的内容,引发信息泄露。动态首页请使用 ESI(Edge Side Includes)或动静分离架构。

  1. 缓存过期时间页签下添加规则,类型选择目录,地址填写 /

  2. 过期时间根据首页内容的更新频率设置,例如 30 秒至数分钟。

  3. 调整规则权重,使根目录规则的权重低于具体路径规则(如 /static/),避免覆盖静态资源的缓存规则。

配置生效后首页内容将由节点直接返回,不再每次回源。详细配置说明请参见配置CDN缓存过期时间

通过 CDN 访问与直接访问源站结果不一致?

问题原因:节点未命中缓存时会转发客户端请求并在请求头中追加特定参数(如 ViaX-Forwarded-For),部分源站会根据这些参数返回不同响应。例如源站判断请求头中是否含有 Via 来识别代理请求,从而做出不同处理。

排查步骤:

  1. 定位导致差异的请求头:先直接访问源站记录返回结果,再用 curl 手动添加 CDN 会追加的请求头访问源站,逐个替换测试,直到复现出不一致的结果。

  2. 调整源站配置:检查源站 Web 服务器对该请求头的处理逻辑,按业务需求修改。

  3. 或在 CDN 侧删除该请求头:若该请求头对业务无实际作用,可在 CDN 控制台配置中删除。

使用 CDN 下载的文件与源站不一致(同名更新)如何解决?

问题原因:源站对文件进行了同名更新(修改了文件内容但未修改文件名),在缓存过期之前 CDN 节点仍直接返回旧缓存,导致下载到的文件与源站不一致。

解决方法:

  1. 方案 1:手动刷新缓存。源站同名更新后,在刷新预热页面提交 URL 刷新(适合单个资源、生效较快)或目录刷新(适合整个目录、范围广但会短暂增加源站回源压力)。

  2. 方案 2:强制刷新绕过 304。当源站文件内容变更但 Last-Modified 时间戳未更新时,CDN 节点通过条件请求(If-Modified-Since)校验后收到 304 Not Modified,判断文件未变更而不更新缓存,此时普通 URL 刷新可能不生效。需调用 RefreshObjectCaches API 并将 Force 参数设为 true 强制回源拉取完整文件。

  3. 方案 3:版本化命名(推荐的长期方案)。建议源站避免同名更新,改为给文件名添加版本号或哈希值(如 style.v2.cssapp.abc123.js),或通过 URL 参数携带版本标识(如 ?v=20260828)。

  4. 方案 4:OSS 源站开启自动刷新。如果源站是 OSS,可在 OSS 控制台开启CDN 缓存自动刷新,当 OSS 源站出现 Object 同名更新时,会自动调用 CDN 的刷新接口刷新对应的 URL。

说明

使用 URL 版本参数时,不可同时开启 CDN 的忽略参数功能,否则版本参数会被忽略,导致该方案失效。若业务必须忽略其他参数,请改用保留指定参数并保留版本参数。

访问资源时出现自定义 404 页面是什么原因?

Web 服务器返回 HTTP 404 状态码时会自动跳转到 404 页面,说明请求的资源在源站上不存在。常见原因包括:URL 生成规则变更、文件被更名或移动位置、链接拼写错误、请求的端口无法访问站点、Web 服务扩展锁定策略或 MIME 映射策略阻止了本请求。

若访问的页面中包含多个资源、仅部分资源不可访问,则页面不会整体跳转到 404 页面。自定义错误页面的配置方法请参见配置自定义页面

配置自定义 403 页面后出现域名跳转或循环重定向如何处理?

为 403 状态码配置自定义错误页面时,如果直接在错误页面设置中配置跳转链接,可能出现域名跳转或循环重定向。请改用以下方式:

  1. 通过重写访问URL功能配置,而非直接在自定义错误页面中设置跳转链接。

  2. 将待重写的 Path 设置为 /,并将目标路径指向正确的 403 静态页面地址(例如 /error/403.html)。

重要

请确保 403 错误页面本身可以正常访问、不会再次触发 403 状态码的重定向,否则会导致循环重定向,页面完全无法访问。

仍未解决怎么办

提交工单前,建议先通过以下方式自助定位:

  • 查看实时日志:在控制台查看具体请求的缓存状态、回源情况和响应码分布,确认问题集中在哪些 URL 或时段。

  • 使用控制台诊断工具:输入出现问题的 URL 进行检测,快速获取解析、回源和响应头信息。

  • 做对比测试:分别通过 CDN 和直连源站访问同一资源,对比响应头和内容差异,判断问题在 CDN 侧还是源站侧。

若自助排查后问题仍未解决,建议收集以下信息后提交工单,以加快定位:

  • 加速域名和具体的请求 URL。

  • 复现问题的 curl -v 完整输出(含请求头和响应头)。

  • 问题发生的大致时间、地域和运营商。

  • 源站类型(OSS、ECS、SLB、第三方源站等)及源站是否支持 Range 请求。

  • 已尝试的排查步骤及各步结果。

  • 若问题涉及缓存命中率,提供控制台命中率截图及对应的时间范围。