摘要

  • RFC 9111 要求看到非安全请求无错误响应的缓存使目标 URI 失效,但这项义务只发生在该请求实际经过的缓存中。
  • 若运营方要声称完成“全局清除”,还必须另外证明缓存路径覆盖、相关 URI 身份和应用派生键均已处理。

先设想一个明确属于假设的事故。客户端发送 PUT,源站返回 204 No Content,控制台随即宣告“全局清除完成”。写请求经过了应用缓存和一处区域网关,但另一处不在该写入路径上的边缘节点,仍在提供由旧对象拼装的集合页。204 状态既没有点名这处边缘节点,也没有指出仍然有效的集合派生键。

这不是 HTTP 缓存机制的缺陷,而是协议规则与运营断言之间的边界。RFC 9110 将定义语义本质上只读的方法称为安全方法,并把 GET、HEAD、OPTIONS 和 TRACE 列为安全方法。可能改变状态的方法需要不同处理。RFC 9111 规定,缓存必须把非安全请求写穿至源站;在转发请求并收到相应响应之前,缓存不得自行生成响应。

响应随后触发一项精确义务:缓存收到非安全方法的无错误响应时,必须使目标 URI 失效。这里的“无错误”是 2xx 或 3xx 状态。失效既可以删除匹配的已存响应,也可以把它标记为无效,从而在再次使用前强制验证。其作用是阻止未经新验证就复用旧响应,而不是宣告系统内所有副本均已消失。

RFC 9111 也允许缓存使其他 URI 失效。同源的 Location 或 Content-Location 值可以成为候选项。这项许可很重要,但它不是通用依赖发现机制。缓存不得依据这条规则让异源候选 URI 失效,也没有义务推断应用从已修改对象派生出的全部产品页、列表、搜索结果、片段、代理键或预计算视图。

拓扑又增加了一重限制。规范明确说明,该机制无法保证全局失效:改变状态的请求只会让它所经过缓存中的响应失效。如果一处缓存仅位于另一条读取路径上,它就没有收到触发本地义务的协议事件。多 CDN、绕过屏蔽层的路径、区域分区,以及 API 缓存与页面缓存的分离,都会把这条边界变成实际控制问题。

运营中常把三句话误并为一句。“源站接受了写入”描述的是变更响应;“途经缓存使目标 URI 失效”描述的是协议要求的本地动作;“所有读者现在都会看到新状态”则涉及全部服务路径、键的派生关系和验证结果。第一句话不能自动证明每一层都完成第二项动作,前两项也不能证明第三项结论。

弥合这一差距需要一份“失效路径收据”。这是本文提出的编辑性控制工具,不是 IETF 定义的协议对象。收据应把非安全请求及其响应与实际承载请求的缓存实例绑定;记录各层规范化后的目标 URI 及本地失效动作;区分目标 URI 的强制失效与 Location、Content-Location 的可选处理;附上应用对集合、搜索、片段和代理键的映射;再保存来自每条重要服务路径的绕缓存探针结果。

有了这份收据,写入成功后的问题便会改变。运营方不再把 204 当作全球缓存事件,而是追问:哪条路径承载了写入,哪处缓存执行了动作,哪些 URI 与派生键被覆盖,又有哪些独立读取证实新状态。只有到这一步,符合协议的本地动作才足以支撑系统级断言。

来源