先给结论:不要用“同一URL”这个说法做对照,而要把请求拆成可复现的四元组——解析目标、请求头身份、网络出口、渲染环境。只有当这四项中只有一项变化时,返回内容的差异才具备对照价值。若四项同时变化,你看到的差异无法归因,后续任何修改都只是猜测。
假设有一个子域名 shop.example.com,你从公司笔记本未登录访问时看到A版页面,用手机4G登录后看到B版页面。你第一反应是解析记录出了问题,于是去查DNS,发现两条记录都指向同一个负载均衡地址。这一步其实已经排除了“解析到不同源站”这个最直接的原因,但很多人到这里就停了,转而怀疑CDN缓存,结果越查越乱。
真正需要做的是:把“设备”和“登录状态”这两个变量分开。设备和登录状态往往是绑在一起的——手机上是已登录状态,笔记本上是未登录状态,你无法判断差异来自哪一项。所以第一步不是查解析,而是制造一个只改一项的对照。
可行的做法是准备两组请求,每组只允许一个维度不同:
如果组一出现差异、组二没有差异,说明返回内容由会话状态驱动,与解析、设备无关。如果组二出现差异、组一没有,才需要往出口IP、UA识别或边缘节点调度方向查。这个动作的结果直接决定下一步:前者去查服务端模板逻辑,后者去查CDN或WAF的分流规则。
肉眼看到的页面不同,不等于服务器返回的文档不同。要拿到可复查的证据,至少记录以下字段:
Vary、Cache-Control、Set-Cookie、X-Cache 一类字段;重点看 Vary。如果它包含 Cookie 或 User-Agent,说明缓存层本来就会按这些维度返回不同副本,这属于设计行为,不是解析异常。反过来,如果 Vary 为空,但同一URL在不同会话下返回了不同正文,那才需要进一步判断是源站动态逻辑还是边缘缓存误判。
这里有一个容易踩的坑:请求量或抓取量某天归零,不能单独证明你的处理是对的。它也可能是日志采样调整、监控口径变化、或流量被另一条规则拦在了更前面。归零只是现象,不是结论。
子域名解析本身只负责把主机名映射到地址,它不携带会话,也不认识登录状态。因此,只要你的多次对照最终都落到同一个或同一组地址上,解析层就不太可能是差异来源。真正产生分支的是解析之后:
判断方法很直接:把响应体里的HTML原文取出来对比。如果两份HTML原文相同,差异是客户端渲染造成的,改解析或缓存都无效。如果HTML原文不同,再往上追是边缘层还是应用层。
第一,不要用“清缓存后重试”作为唯一手段。清缓存会同时改变边缘缓存状态和本地状态,变量一下变两个,即使问题消失了也不知道是谁的功劳。第二,不要在未固定出口的情况下用手机流量做对照,运营商出口和WiFi出口可能命中不同边缘节点,这会伪装成“设备差异”。
如果必须做跨网络对照,至少记录两次请求各自的出口IP,确认它们是否落在同一网段或同一调度区域。这一步的结果会影响你下一步是去查节点配置,还是回到应用层排查。
假设你最终发现:未登录返回200且HTML为A,登录后返回200且HTML为B,Vary 中包含 Cookie,两次请求出口IP相同。那么结论是:这是应用层按会话返回不同内容,属于预期行为,解析无误。下一步不是改DNS,而是确认这种差异是否符合业务预期,以及是否需要让搜索引擎看到的那一版保持稳定。如果 Vary 为空、出口IP相同、HTML却不同,才需要继续查源站模板或实验开关。整个对照过程的价值,就在于让每一步都能排除一个变量,而不是靠反复刷新碰运气。