hsyun(火烧云)hsyun.io client
误区整理

公开状态页显示恢复,为什么本地仍可能异常:时间线、组件范围与缓存边界

状态页、组件范围、HTTP 缓存和客户端计时描述不同层面。恢复公告不能清除所有缓存或重建所有连接;把公告时间、受影响组件、缓存年龄与请求阶段并排,才能判断本地异常是否仍在原事件范围内。

状态页显示事件已经解决,电脑仍加载失败,手机却恢复正常。此时最容易出现两个过度结论:要么认为状态页不可信,要么认为电脑一定有问题。其实两边描述的是不同观察层。

状态页只覆盖它声明的组件、地区和时间;本地请求还要经过解析、连接、缓存和应用处理。状态页组件恢复、缓存重新验证和客户端新连接是依次但不必同步发生的环节。

先读公告覆盖什么,而不只看颜色

抄下事件开始、恢复时间、组件名称、地区与已知限制。若公告只写 API,而失败任务还依赖登录、静态资源和下载组件,“API 已恢复”不能代表完整任务链全部恢复。若公告覆盖另一区域,本地失败也不在它的直接结论范围。

状态页转绿不保证所有地区与设备同步恢复,本地一次失败也不能单独证明公告错误或服务再次中断。公告和本地日志应该并排使用,而不是要求其中一个推翻另一个。

新鲜缓存可以继续复用旧响应

RFC 9111 以新鲜度寿命和当前年龄决定缓存响应是否可直接复用,源站恢复不会自动让所有副本过期。客户端缓存、中间代理与 CDN 都可能保存响应;只要规则允许,仍新鲜的副本不需要为了上游状态变化主动重新请求。

响应变陈旧后,缓存通常通过条件请求重新验证。no-cache 表示复用前要验证,不等于从不存储;no-store 才是禁止存储的指令;must-revalidate 则限制陈旧响应未经成功验证就继续使用。看到其中一个词,不能把其他含义一起套上。

Cloudflare 官方文档还说明,stale-while-revalidate 可以在限定窗口先返回陈旧内容,同时在后台更新。它是一个具体实现例子,证明短时间差异存在合理机制,但不能据此断言目标站一定采用 Cloudflare 或相同配置。

相同 URL 也可能命中不同副本

RFC 9111 的 Vary 规则会把指定请求头纳入缓存键。语言、编码能力或其他请求条件不同的设备,即使访问相同 URL,也可能命中不同存储响应。Vary 可以让相同 URL 因请求头不同而使用不同缓存键,因此不同设备可能看到不同副本。

这不是说所有设备差异都来自 Vary。浏览器版本、登录状态、解析结果与网络路径也会改变请求。它的价值是提醒记录者:不要只写“同一个网址”,还要保留设备、浏览器、是否登录和网络条件。

用请求阶段找到公告之外的停点

W3C Resource Timing 区分域名解析、建立连接、发出请求、收到首字节和响应结束。浏览器不一定暴露跨源的完整细节,普通记录仍能写下“是否连上”“多久开始返回”“返回后是否完整”。

若请求卡在解析或连接,问题可能发生在状态页所述应用组件之前;若很快收到首字节但内容旧,缓存解释更值得验证;若内容返回完整而应用仍失败,登录状态或本机应用阶段仍需单独观察。阶段定位只能缩小范围,不能自动产生因果结论。

两台设备做受控交叉,而不是轮流乱试

先在原设备保留原会话做一次,再建立新连接做一次;随后在第二台设备用相同网络与任务重复。不要同时清缓存、换 DNS、换节点和升级客户端,否则每个变化都可能解释结果。

在同一设备上比较原会话与新连接,再在第二台设备重复同一任务;只有公告范围、请求条件和时间窗一致时才比较结果。如果新连接恢复而原会话仍旧,缓存或连接复用线索增强;如果两台设备都在相同阶段失败,且公告明确覆盖该组件与地区,可以把完整时间线提交给支持方。

公开状态页显示恢复,为什么本地仍可能异常:时间线、组件范围与缓存边界 配图 1
公开状态页显示恢复,为什么本地仍可能异常:时间线、组件范围与缓存边界 配图 1

记录公告组件、地区、恢复时间、请求阶段、缓存年龄迹象与连续成功次数,再决定是否继续等待或提交问题。至少保留两次连续成功,避免把偶然一次返回当成稳定恢复。

年龄字段只能说明副本时间,不能直接说明事件原因

RFC 9111 的 Age 表示响应在缓存链中估算的年龄。它要配合 Date、新鲜度寿命和缓存指令,才能判断副本是否仍可复用。看到 Age 增长,能说明这份响应不是每次都从源站全新生成;看不到 Age,则可能是未缓存、字段未暴露或由另一层处理,不能反推“绝对没有缓存”。

比较两台设备时,记录响应是否包含 Age、ETag、Last-Modified 或 304。若一台持续收到同一 ETag 的旧内容,另一台取得新版本,缓存或条件请求差异成为可检验线索。字段相同却任务结果不同,则应回到连接、登录状态或应用处理阶段。

四格表把范围与现场对齐

第一格是“公告覆盖、两台都恢复”:保留连续成功次数后结束观察。第二格是“公告覆盖、两台都失败”:在固定窗口复测并提交组件、地区、错误和请求阶段。第三格是“公告覆盖、设备分歧”:优先比较缓存键、会话与连接,不急着宣布再次中断。第四格是“公告不覆盖、本地失败”:把它作为独立问题,不借原事件作因果说明。

这张表要求先填公告范围,再填设备结果。若先从本地失败出发,人很容易把任何公开事件都当成原因;若只看状态页,又会忽略实际任务仍未完成。

恢复后的首个请求最容易造成误判

Cloudflare 文档中的 stale-while-revalidate 说明一个典型顺序。过期后的首个请求可以先得到陈旧响应,同时触发后台更新;后续请求才取得新内容。即使目标站并未采用这项配置,这个机制也提醒我们不要把第一条结果当作整个恢复过程。

因此每个窗口至少做两次同任务请求,并保留顺序。第一次旧、第二次新,与两次都旧或两次都失败,是不同证据。为了减少副作用,不要高频刷新;按固定间隔足以观察变化,也避免给服务增加额外负载。

提交问题时只交必要证据

可交付记录应包含公告链接的非敏感标题、组件、地区、恢复时间,设备与浏览器版本,网络类型,请求阶段和错误原文。不要附上账号、验证码、Cookie、授权头或付款资料。若截图含个人信息,先遮蔽再提交。

问题描述用“在某时间、某组件范围、某设备上连续两次未完成任务”,不要写成“平台又宕机”或“缓存服务器坏了”。前者可复查,后者超出现场证据。

先定义“同一请求条件”

受控比较至少固定 URL、登录状态、语言、浏览器版本和网络。若一台设备登录、另一台未登录,Vary、Cookie 或私有缓存都可能让响应不同;此时不能把差异只归给地区或组件。可以选择都退出登录比较公开页面,再分别记录登录任务,避免两种条件混在一列。

缓存键并不一定只由 URL 组成,站点也可能按编码、语言或设备能力返回不同表示。看到 HTML 不同前,先比较内容类型、编码、ETag 和最后修改时间;这些字段能帮助确认是否真是两个版本,仍不能证明是哪一层生成。

观察结束要保留反证

若原会话和新连接都连续成功,应同时保留之前失败的时间点,避免记录只剩成功结果。若另一个地区仍有报告,把本站结论限定为本地设备与本地网络恢复,不扩展到全局。这样的结尾既能支持当前行动,也不会覆盖状态页之外的未知范围。

若无法取得响应头,也可以诚实标记为不可见,并用固定间隔、内容版本和任务结果代替。缺字段会降低归因能力,却不会让记录失效;真正应避免的是把不可见写成没有缓存,或把一次刷新后成功写成已经找到原因。

本文不把状态页当服务保证,也不从客户端日志推断攻击、节点故障或运营商责任。结论只覆盖实际公告范围和观察样本;证据能支持到哪一层,说明就停在哪一层。

资料来源

  • IETF / RFC Editor:《RFC 9111: HTTP Caching》,发布或更新于 2022-06-01
  • Cloudflare Docs:《Origin Cache Control》,发布或更新于 2026-06-30
  • 万维网联盟(W3C):《Resource Timing》,发布或更新于 2026-04-20