先给结论:二级域名本身不决定缓存行为,但它是排查的锚点。当同一个二级域名在浏览器、CDN 边缘节点和源站返回不同内容时,不要从“哪一层坏了”入手,而要先确定每一层看到的请求主机名、缓存键和响应头是否一致。定位顺序应是:固定一个二级域名作为观测入口,逐层对比响应头,再判断差异来自缓存键设计、回源路径还是内容协商。
假设你有一个二级域名 shop.example.com,源站同时服务新版商品页和旧版模板。运维给 CDN 配置了缓存,浏览器也带本地缓存。有用户反馈:同一路径下,有时看到带促销横幅的新版页面,有时看到没有横幅的旧版页面。此时你面对的不是“二级域名坏了”,而是多层缓存对同一资源给出了不同版本。
这个情境成立的前提是:该二级域名确实由多套缓存共同服务,且各层缓存策略不完全相同。如果只有源站直连、没有中间缓存,那么版本差异更可能来自源站发布流程或动态渲染,而不是缓存分层问题。
页面外观只能说明用户看到了什么,不能说明版本从哪里来。更可靠的动作是固定同一个二级域名和路径,分别用浏览器开发者工具、命令行请求和 CDN 回源日志对比响应头。重点关注 Age、Cache-Control、ETag、Vary 以及 CDN 自己添加的缓存状态字段。
Age 较大且内容陈旧,通常说明命中了中间缓存,而不是源站刚发布。Cache-Control 在浏览器和 CDN 上被改写,说明两层的策略不同步。ETag 相同但内容不同,说明缓存键或内容协商维度没有覆盖真正变化的因素。Vary 缺失或过宽,会让同一 URL 因设备、语言或 Cookie 返回不同版本。这一步的结果会直接影响下一步:如果各层响应头显示缓存键一致,却仍返回不同版本,就要转向回源路径和发布流程;如果缓存键本身不一致,问题在配置层,继续查源站意义不大。
很多团队把二级域名当作天然隔离,认为 shop.example.com 和 www.example.com 互不影响,但缓存键通常由协议、主机名、路径和查询串共同组成。若 CDN 配置里忽略了查询串,或源站根据 Cookie 返回不同模板,而缓存层没有把 Cookie 纳入键,就会让不同用户拿到同一份缓存副本。
判断方法很具体:构造两个只差一个查询参数或一个 Cookie 的请求,观察是否命中同一缓存对象。如果两者返回相同内容,而源站单独回源时返回不同内容,说明缓存键漏掉了区分维度。此时动作是补全缓存键,而不是清空全部缓存。补全后要重新验证同一路径在新旧参数下是否各得其版本,再决定是否保留旧缓存。
另一种常见情况是源站已经发布新版,但 CDN 尚未过期,于是边缘返回旧版;或者 CDN 已刷新,但浏览器本地缓存仍持有旧版。这类差异不是缓存键错误,而是刷新时序问题。此时仅清 CDN 缓存可能不够,因为浏览器端仍可能命中本地副本。
可区分的证据是:同一二级域名在无痕窗口或禁用本地缓存后返回新版,普通窗口仍返回旧版,说明问题在浏览器层;若所有客户端都返回旧版,但源站直连返回新版,说明问题在中间缓存层。两种情况的处理动作不同:前者需要调整本地缓存策略或版本化资源路径,后者需要刷新边缘缓存并检查回源缓存头。
假设排查后确认是 CDN 缓存键漏掉了设备类型,导致移动端和桌面端共用一份缓存。修复动作是给缓存键加入设备维度,并观察修复后同一路径在不同设备上的响应是否分离。如果分离成功,下一步是评估缓存命中率变化是否可接受;如果分离后仍混版,则需要检查源站是否在响应中正确声明了 Vary。
如果排查后确认是源站发布未完成,缓存层只是如实返回旧版,那么清缓存只会短暂掩盖问题,源站发布完成后仍可能再次分叉。此时正确动作是先冻结缓存刷新,等源站发布完成并验证回源内容一致,再统一刷新边缘缓存。这个顺序能避免“刷新后旧版被重新缓存”的反复。
定位一致性问题的核心不是记住某个缓存层,而是建立一条可验证的链路:固定二级域名,逐层读取响应头,确认缓存键和回源内容,再根据差异来源选择修复动作。只有每一步的观测结果能决定下一步动作,排查才不会退化成反复清缓存。