先区分两类不一致:一类是同一URL在不同缓存层返回不同内容版本,另一类是日志里同一URL的抓取记录本身指向不同版本。前者要靠对比缓存键和回源响应,后者要靠日志中的状态码、响应体长度和UA分布交叉验证。不能仅凭某一层返回旧版本就断定缓存配置错误,因为回源本身可能已经返回旧版本。
多层缓存通常包括CDN边缘节点、中间反向代理和源站应用缓存。判断顺序应从最外层向内逐层剥离。具体动作是:用同一URL、同一请求头分别请求边缘节点、回源地址和源站直连地址,记录每次响应的Age、ETag、Last-Modified和响应体长度。如果边缘节点返回的ETag与源站直连不同,说明边缘缓存持有旧对象;如果两者相同但日志中蜘蛛抓取到的内容版本不同,则问题更可能出在回源链路或应用层缓存。
这一步的结果直接决定下一步:边缘层不一致时,优先检查缓存键是否包含会变化的请求头(如Accept-Encoding或自定义版本头);回源链路不一致时,才需要进入源站和应用缓存排查。跳过分层直接清空全部缓存,会暂时掩盖问题,但无法解释为什么只有部分URL出现例外。
条件一:不一致只在带特定请求头的抓取中出现。此时应把日志按UA和请求头分组,对比同一URL在不同请求头下的响应版本。若差异仅出现在Accept-Encoding不同的请求中,说明缓存键可能未包含该维度,导致压缩版本与未压缩版本互相覆盖。实施动作是固定一组请求头重复抓取同一URL,观察版本是否稳定;如果稳定,则问题在缓存键设计,而非内容本身。
条件二:不一致在无差别请求中也随机出现。此时应检查源站是否有多台应用服务器或读写分离节点,日志中同一URL的响应长度是否在几个固定值之间跳动。若长度呈周期性变化,可能是应用层缓存过期时间不同步;若长度无规律,则更可能是回源时命中了不同后端。此时的实施动作是给源站响应增加可区分的版本标识(如自定义响应头),再回看蜘蛛日志中该标识的分布,以判断抓取是否命中了不同后端。
蜘蛛日志分析的价值在于它记录了抓取时刻的实际响应,而不是事后推测。可用的区分证据包括:同一URL的状态码是否在200和304之间交替、响应体长度是否出现两个稳定值、抓取间隔是否与缓存TTL吻合。如果304出现频率突然升高,且伴随响应长度变化,说明缓存协商机制可能返回了不同版本的验证结果。
需要注意的是,请求量或抓取量归零不能单独证明某个缓存层已修复。它还可能由抓取预算调整、robots.txt临时限制或站点地图更新导致。因此,判断一致性是否恢复,应同时观察多组URL的响应版本是否收敛,而不是只看总量变化。
个别样本成立但规模化后出现例外,通常是因为样本URL的缓存键组合恰好一致,而全量URL中存在参数顺序、大小写或尾部斜杠差异。此时不能直接照搬样本结论。实施动作是抽取一批URL,按参数排列组合生成变体,分别请求并记录返回版本。如果同一资源的多个变体返回不同版本,说明缓存键未规范化,需要在边缘层统一归一化规则。
边界在于:如果站点本身允许同一资源通过多个URL提供不同内容(例如多语言或多币种),则版本差异是预期行为,不应强行统一。此时应改为在日志中标记这些URL的预期版本,再检查实际返回是否偏离预期。只有偏离预期的差异才需要修复。
假设某站点有CDN和源站两层缓存,蜘蛛日志显示URL A在上午返回长度1200字节,下午返回长度1350字节。先固定请求头直连源站,若源站始终返回1350字节,则CDN层持有旧版本;再检查CDN缓存键是否包含Vary指定的头。若缓存键包含该头而抓取请求未发送该头,则CDN可能按默认版本返回,造成日志中的版本差异。这个例子只用于说明比较方法,不代表任何真实站点数据。
最终判断一致性是否解决,应回到蜘蛛日志中同一组URL的响应版本是否在多个抓取周期内保持稳定。稳定后再逐步放开抓取限制,观察是否重新出现分化。如果分化再次出现,说明缓存键或回源规则仍有未覆盖的维度,需要回到分层排查的第一步重新确认。