发布日期:2026 年 9 月 22 日 · RootGS 技术编辑
服务器上的文件已经更新,管理员打开页面正常,客户却一直看到旧价格或旧按钮。这时反复清理所有缓存可能暂时有效,却很难解释根因。缓存可能存在于浏览器、服务工作线程、CDN、反向代理和应用内部,不同层的失效方式也不相同。本文围绕一次网页更新,介绍如何找出旧内容来自哪里,并把发布和回退设计成可验证的流程。
一、先确定旧的是页面、资源还是接口数据
页面上的一处错误,可能来自旧HTML、旧JavaScript、接口缓存或应用数据缓存。先记录完整URL、出现时间、账号状态、浏览器和网络,再比较旧内容具体对应哪个请求。不要只保存首页截图,否则无法区分页面模板没有更新,还是新页面调用了旧数据。
浏览器开发工具可以查看响应内容、请求头、响应头和资源来源。对照实际业务版本标识或内容摘要,比只看文件修改时间更可靠。同一页面若依赖多个节点,还需核对是不是部分节点仍在提供旧版本;缓存并不是所有新旧内容混杂现象的唯一原因。

二、按访问路径逐层比较,不要一开始就全量清空
先比较同一URL在不同客户端的结果,再检查公网入口返回的内容与源站受控验证结果。响应中的Age、ETag、Last-Modified及服务商特有的缓存状态可以提供线索,但缺少某个头不代表没有缓存。查询时应保持域名、路径、必要请求头和登录状态一致,避免比较了不同版本的响应。
访问源站时要遵守原有访问控制,并保留正确的主机名和TLS验证。直接用IP访问可能进入另一个虚拟主机,不能把那个结果作为原站内容的证据。浏览器强制刷新、禁用浏览器缓存或curl新请求,也不一定绕过CDN、服务工作线程与应用缓存。
三、读懂no-cache、no-store和private的区别
no-cache并不等于禁止存储,它要求在复用响应前进行相应验证;no-store表达不要存储该请求或响应的缓存要求。private用于限制共享缓存存储,仍可能允许用户自己的浏览器缓存。它们解决的不是同一个问题,不能把几个词视为越多越安全的万能组合。
缓存新鲜度、验证器与响应是否允许存储也需要一起考虑。304表示可继续使用已保存的表示,不是一份重新下载的正文。若验证器没有随着实际内容正确变化,客户端可能继续复用不该复用的版本。修改响应头后,仍需检查之前已经被保存的内容与失效过程。
具体CDN配置可能覆盖源站缓存头,因此验收必须看实际公网响应,而不是仅检查应用配置里写了什么。
四、个性化页面必须把共享缓存边界设计清楚
购物车、账户资料和客户专属价格不应因为缓存键只包含路径,就被不同用户共用。先确认内容受哪些因素影响,再决定不进入共享缓存,或采用经过验证的隔离方案。Cookie、认证头、语言、设备或区域是否参与缓存行为,需结合实际平台配置核查。
Vary用于说明响应选择依赖哪些请求头,但不能替代完整的权限设计,也不能假定所有中间服务都按你的设想处理。大量变化维度还会增加缓存碎片。对敏感页面,应优先确保不会跨用户复用,再讨论命中率;优化速度不应建立在权限边界模糊的基础上。

五、静态资源用内容版本,HTML保留可更新入口
对长期可缓存的CSS、JavaScript和图片,可以使用随内容变化的文件名或可靠版本标识。新页面引用新文件后,旧文件不必立即删除,因为尚未更新的HTML或正在使用的客户端仍可能需要它们。这样能减少依赖全网同时清缓存的发布方式。
HTML与配置入口则需采用适合业务更新频率的缓存策略,并验证它们会切换到正确的资源版本。部分平台会忽略或规范化查询参数,不能默认在URL后添加任意参数必定改变缓存键。清理缓存时先确认要清理的对象和规则,避免全量清理突然把流量压回源站。
六、回退要覆盖缓存中的新旧版本组合
如果只把HTML回退到旧版,却已经删除旧资源,客户可能看到无法执行的页面。反过来,新JavaScript调用旧接口也可能失败。发布计划应标明版本兼容窗口、资源保留策略、接口变更方式和回退顺序,不能把回退简化为覆盖几个文件。
应用内部缓存的键结构或数据格式改变时,也要考虑旧进程与新进程并行运行。可以通过版本化命名空间或明确失效流程降低冲突,但具体方案需结合业务一致性要求。缓存内容不能成为唯一数据来源,重要业务状态仍应有可核对的权威记录。

七、用不同身份与入口完成发布验收
检查匿名用户、登录用户和不同权限账号,覆盖主要页面、资源文件及关键接口。比较不同网络或边缘节点时记录实际请求时间和响应内容,避免把一台电脑成功当作全站成功。对于登录页面和客户数据,还应验证另一个账号不能取得前一个账号的缓存响应。
最后记录发布版本、命中状态、源站负载变化和回退验证结果。缓存治理的目标是让该复用的内容稳定复用、该更新的内容按预期更新,而不是遇到问题就永远关闭所有缓存。找到具体层级和缓存键,才有办法既保留性能又控制一致性。
