先给结论:不要从“哪个缓存错了”入手,而要先确认各层缓存对同一内链请求返回的版本差异是否稳定可复现。如果差异只在特定入口、特定登录态或特定时间窗口出现,优先怀疑缓存键设计;如果差异稳定出现在同一入口,再怀疑上游内容源或改写逻辑。定位顺序决定了你是保留现有缓存结构、改写键规则,还是退出某一层缓存。
多层缓存下,同一个内链请求可能经过浏览器缓存、CDN、反向代理、应用层缓存和模板片段缓存。要定位一致性,第一步是固定一组观察点,而不是同时刷新多个页面凭感觉判断。
如果直连源站和经过 CDN 的结果不同,差异在 CDN 或更外层;如果两者一致但与浏览器看到的不同,差异可能在浏览器缓存或本地存储。这个判断直接影响下一步:差异在越外层,越应该先检查缓存键和过期策略,而不是改内链生成代码。
多层缓存返回不同版本,最常见的原因是缓存键没有覆盖真正影响输出的变量。内链常随以下因素变化:
判断方法很直接:构造两个只在一个变量上不同的请求,观察返回的内链是否不同。如果不同,而缓存键里没有这个变量,那么缓存命中就会把 A 变量的结果返回给 B 变量。此时保留现有缓存层的前提,是把该变量加入键或改为不缓存该片段;如果业务上无法接受键膨胀,才考虑退出这一层缓存。
实际动作:先给缓存键补上缺失变量,再重复同一组请求。若差异消失,说明问题在键设计;若差异仍在,继续向上游排查。这个动作的结果决定了你是继续保留该缓存层,还是把它从关键内链路径上移除。
缓存只是放大器,不是唯一来源。要区分两者,可以临时让某一层缓存失效或绕过,观察内链是否仍然出现多个版本。
过期时间不一致是容易被忽略的原因:短过期层已经刷新,长过期层仍返回旧内链,用户在不同请求中就会看到不同版本。此时要么统一各层过期策略,要么让内链这类强一致内容不进入长过期层。选择取决于业务能否接受短暂不一致。
三种取舍各有前提,不需要同时满足。
不要因为一次观察到不同版本就立刻退出缓存。先确认差异是否可复现、是否稳定、是否只影响内链。如果差异只在缓存刷新瞬间出现,且很快收敛,保留并调整过期策略通常比退出更合适。
假设某站点有 CDN 和反向代理两层缓存,同一文章页在未登录时链向 A、B、C 三个页面,登录后链向 A、B、D。若缓存键只包含 URL,不含登录态,那么登录用户的请求可能命中未登录缓存,返回 C 而不是 D。
此时可以构造一个两行两列的变量矩阵:登录/未登录 × 直连源站/经过缓存。如果直连源站两行都正确,经过缓存后未登录行正确、登录行错误,就能把问题锁定在缓存键遗漏登录态。动作是把登录态加入键或对该片段禁用缓存,然后重跑矩阵。若登录行恢复正确,说明改写有效;若仍错误,再检查反向代理是否在 CDN 之前已经混用了缓存。
这个例子中的数字和页面名称都是假设,只用于说明比较方法,不代表任何真实站点结果。
请求量下降、抓取量变化或某个入口暂时返回统一版本,都不能单独证明缓存问题已解决。它们还可能是流量波动、抓取策略调整或缓存刚好处于同一过期窗口造成的。可靠的做法是重复同一组受控请求,确认在多个时间点、多个入口下返回的内链版本一致。
如果一致性只在部分入口恢复,说明还有一层缓存或一个变量未被覆盖。下一步不是扩大缓存清理范围,而是回到变量矩阵,找出仍未受控的那一维。只有当你确认所有影响内链的变量都已进入缓存键或已排除在缓存之外,才适合判断该缓存层可以保留。