先做一件事:把同一份页面资料分别从浏览器、CDN节点和源站直接取回,逐字节对比。如果三者内容不一致,问题通常不在百度收录本身,而在缓存层返回了不同版本。定位顺序应当是先确认差异存在,再判断差异发生在哪一层,最后决定是清缓存、改缓存键还是改回源策略。下面以你手上一个具体页面为对象,给出可执行的处理路径。
面对“不同节点返回不同内容”的现象,第一反应往往是刷新缓存。但清缓存会让证据消失,之后无法判断问题是否复发。更稳妥的做法是先取证。
假设你有一个页面 https://example.com/a,用以下方式各取一份:
Cache-Control: no-cache 请求头直接访问源站,或用回源IP加 Host 头访问,得到源站版本。把三份响应的正文、Last-Modified、ETag、Age、X-Cache 一类头部字段并排记录。这一步的产出是一张差异表,而不是一句“缓存有问题”。只有确认差异真实存在,后续动作才有方向。
“返回不同版本”在技术上至少有三种形态,处理方式完全不同。
常见原因是缓存键设计过粗。比如同一URL根据 User-Agent 或 Accept-Language 返回移动版和桌面版,但CDN只按URL缓存,就会把先到的版本发给所有人。判断依据是:同一URL在不同请求头下源站本就返回不同内容,而边缘节点只保留了一份。
正文相同,但 Cache-Control、Vary、Expires 在不同层被改写。例如源站声明 max-age=60,中间层却改成更长或更短。这类差异不会让用户看到不同页面,却会让抓取端拿到互相矛盾的缓存指令,进而影响后续抓取节奏。
最需要警惕的一种:源站返回200,某个边缘节点却返回404或503。如果抓取端正好命中该节点,可能据此判断页面失效。此时要核对的是该节点的回源日志和源站当时的响应,而不是直接改页面。
取证之后,用一个可区分的实验缩小范围。核心思路是改变一个变量,看差异是否跟着变。
User-Agent 后版本变化,说明缓存键缺少必要的区分维度。这一步的实际动作是:在实验记录里写清“哪个变量变化时差异出现”。如果差异只在换节点时出现,下一步就去看该节点的缓存配置和回源记录;如果只在换请求头时出现,下一步就是补 Vary 或调整缓存键。动作的结果直接决定后续是运维侧处理还是应用侧处理。
假设某页面在A节点返回旧标题,在B节点返回新标题。直觉会认为是CDN没刷新。但直连源站后,发现源站有两台应用服务器,其中一台仍加载着旧配置。此时刷新CDN无效,因为回源拿到的仍可能是旧版本。这个例子说明:边缘不一致只是表象,回源结果才决定缓存内容。 判断顺序应是先确认源站是否一致,再处理缓存层。
这个例子的适用边界是:源站存在多实例且配置未统一。如果源站只有单实例且回源结果稳定,那么差异更可能出在缓存键或节点分布上,不能照搬这个结论。
无论采取哪种修复,验证都不能只测一次。至少覆盖:多个地区节点、带与不带关键请求头、连续多次请求。观察 Age 是否从0开始增长、X-Cache 是否从MISS转为HIT、不同节点是否收敛到同一版本。
需要提醒的是,抓取量或某个节点请求量归零,并不能单独证明问题已解决。可能是抓取端暂时降低了该目录的抓取频率,也可能是节点被临时下线。合理解释还包括:缓存刚被清空导致短期回源增加、监控采样窗口变化、请求被调度到其他节点。要结合源站日志和缓存命中记录一起看,而不是只看一个指标。
另外,robots.txt 的抓取限制不等于可靠的索引移除,站点地图也不保证收录。缓存一致性修好之后,收录状态仍可能因页面质量、链接关系和抓取预算而变化,这两件事要分开评估。最后,把本次的差异表、实验记录和修复动作归档,下一次遇到类似现象时可以直接复用判断路径,而不是从清缓存重新开始。