先给结论:多层缓存导致同一 URL 返回不同版本时,不要从日志里直接找“哪个版本是对的”,而要先按请求路径分层,把 CDN、反向代理、应用缓存、对象存储各自的命中记录与响应头对齐,找出第一处版本分叉的位置。爬虫日志分析在这里的作用不是判断内容好坏,而是提供每条抓取请求的时间、UA、URL 和状态码,再与各层缓存日志做时间窗比对。
假设某站点要把一批旧活动页下线,但保留其中仍然有效的报名入口。运维在 CDN 层对旧路径设置了较长缓存,反向代理层保留中等缓存,应用层则对部分页面做了页面级缓存。上线后,爬虫日志里同一 URL 出现两种状态码和两种内容长度。此时不能直接判定“缓存坏了”,因为多层缓存本来就允许不同层持有不同时间的副本。要定位一致性问题,需要先确认版本分叉发生在哪一层,再决定是清缓存、改规则,还是保留旧版本。
对每条可疑抓取记录,先看响应头里能标识缓存来源的字段,例如 Age、Cache-Control、Via、X-Cache 以及各层自定义的命中标识。把同一 URL 在相近时间内的记录按这些标识分组,通常会出现三类:
这个分组动作会直接影响下一步:如果分叉只在 CDN 层,优先核对缓存键和刷新范围;如果分叉在应用层,就要检查发布流程是否写入了两个版本。
内容长度和正文摘要不一致,不一定代表版本不同。同一份内容经过不同压缩算法、不同字符集声明或不同移动端适配规则后,长度也会变化。判断时至少比对三项:正文中的关键标识(如活动结束日期或报名按钮文案)、响应头中的内容编码,以及页面内引用的资源版本号。如果关键标识一致而只有长度不同,优先怀疑压缩或编码差异;如果关键标识本身冲突,才按版本分叉处理。
这一步能避免把编码问题误判为缓存不一致,从而少做一次无谓的全量刷新。
单条日志无法证明哪一层先返回旧版本。取一个覆盖发布时刻的时间窗,把爬虫请求时间、各层缓存写入时间和源站更新时间排成序列。假设源站在 10:00 更新,CDN 在 10:05 仍返回旧版本,而反向代理日志显示 10:02 已收到新版本,那么分叉点在 CDN 到源站的回源链路或缓存键上,而不是应用发布失败。
如果时间窗内各层写入时间都晚于源站更新,却仍返回旧内容,就要检查是否存在多个源站节点、灰度发布残留或对象存储的多版本配置。请求量归零或某层命中率下降,也可能是抓取频率变化、UA 被限流或日志采样导致,不能单独作为版本一致性的证据。
定位到分叉层后,处理方式取决于旧内容是否仍有价值:
完成一次处理动作后,下一步不是立刻扩大刷新范围,而是用同一时间窗复查爬虫日志与各层缓存日志是否重新对齐。只有对齐后,才考虑把该 URL 的缓存策略固化到发布流程中。
robots.txt 的抓取限制不等于可靠的索引移除,缓存层返回的版本差异也不会因为限制抓取而自动消失。站点地图不保证收录,HTTPS 不保证安全无漏洞或排名,这些都与版本一致性判断无关。不同搜索引擎对缓存和抓取的处理方式需要分别核查,不能把一层的命中记录直接套用到另一层。
把版本分叉定位到具体层,再决定刷新、拆分还是退出,才能让爬虫日志分析真正服务于旧内容退出的取舍,而不是停留在“清一次缓存看看”的循环里。