先给结论:当 CDN、反向代理和页面缓存各返回不同版本时,不要急着清空全部缓存,而应先把“版本差异”缩小到具体层。做法是固定一个测试 URL,分别绕过每一层请求,记录响应头、正文片段和缓存命中状态;如果差异只在某一层出现,就保留其他层、只处理该层。这样做的代价是需要额外维护带绕过参数的测试入口,但能避免因全量清缓存导致源站压力上升和正常缓存被误伤。
多层缓存返回不同版本,常见原因有两类:一类是各层缓存了不同时间点的正文,另一类是同一份正文被不同层附加了不同响应头或做了压缩、重写。两者处理方式不同,先要区分。
可以固定一个带唯一查询参数的 URL,连续请求多次,记录每次返回的正文长度、关键片段和缓存相关响应头。如果正文片段不同,说明是内容版本不一致;如果正文相同但响应头或编码不同,说明是转换或头部处理不一致。这个动作的结果决定下一步:内容版本不一致要追发布与刷新链路,头部不一致则要查各层配置是否对同一资源做了不同处理。
需要提醒的是,请求量或抓取量突然归零,不能单独证明缓存处理正确。它也可能是抓取预算调整、测试入口被限制或统计口径变化造成的,必须结合源站日志和其他层响应一起判断。
面对多层缓存版本不一致,实际可选的处置通常落在三种动作上,各有适用条件。
适用前提是差异只出现在一层,且其他层的缓存行为符合预期。例如反向代理返回旧正文,而 CDN 和源站一致。此时保留 CDN 与源站缓存,只刷新反向代理层,代价最小。执行后再次用同一测试 URL 绕过各层请求,确认差异消失。如果差异仍在,说明问题不在该层,应回到上一步重新缩小范围。
适用前提是差异反复出现,且每次都要人工刷新。此时可以给资源加统一的版本标识,让各层按同一规则判断是否命中。代价是发布流程变复杂,旧版本资源可能短期仍被引用。适合更新频率高、且能接受发布流程改造的站点。若站点更新很少,这种改造的收益有限。
适用前提是某一层长期无法与其他层对齐,且该层带来的性能收益不足以抵消维护成本。退出后请求直接落到下一层或源站,一致性更容易保证,但源站压力和响应时间会上升。这个动作适合作为临时验证手段,确认问题是否由该层引起;是否长期退出,要看源站能否承受对应请求量。
不要只看一个页面的返回结果。至少同时观察三类证据,才能把原因分开。
如果带唯一参数的请求始终返回新版本,而不带参数的请求返回旧版本,问题更可能出在缓存键或刷新规则,而不是源站发布。反之,如果带唯一参数也返回旧版本,就要继续往源站和发布链路查。这个判断结果直接决定下一步是改缓存键配置,还是查发布流程。
假设某站点有 CDN、反向代理和页面缓存三层。测试发现:不带参数请求返回旧标题,带唯一参数请求返回新标题;绕过 CDN 请求反向代理,返回新标题;直接请求源站,也返回新标题。
这组结果说明差异集中在 CDN 层,且与缓存键有关。此时保留反向代理和页面缓存,只处理 CDN 的缓存键或刷新规则即可。处理后再用同一组请求验证:不带参数请求应返回新标题。如果仍返回旧标题,则需要确认 CDN 刷新是否覆盖了该 URL 的全部变体。这个例子的数字和层数均为假设,用于说明比较方法,不代表任何真实站点配置。
定位到具体层之后,动作要能改变下一次观察结果,否则无法验证。常见动作包括:刷新该层指定 URL、调整缓存键规则、临时绕过该层请求。每个动作执行后,都要用同一测试 URL 重新采集响应,比较正文和响应头是否收敛。
如果多次刷新后差异仍反复出现,说明问题可能不在缓存层,而在发布流程或版本标识规则。此时继续清缓存只会重复消耗,应转向检查发布链路。robots.txt 的抓取限制不等于可靠的索引移除,站点地图也不保证收录;这些与缓存一致性不是同一问题,不要用它们替代缓存层的定位动作。
最后,若站点同时依赖搜索引擎、平台推荐和广告渠道,缓存版本不一致对它们的影响并不相同:搜索引擎抓取的是某一时刻的响应,平台推荐和广告落地页可能各自缓存。定位时先明确当前要解决的是哪一类访问路径,再决定保留、改写还是退出对应缓存层。