本文作者:V5IfhMOK8g

说出来你可能不信,如果你觉得51网不对劲,先从缓存管理查起

V5IfhMOK8g 昨天 129
说出来你可能不信,如果你觉得51网不对劲,先从缓存管理查起摘要: 说出来你可能不信,如果你觉得51网不对劲,先从缓存管理查起你打开页面觉得内容怪怪的、样式没更新、接口返回老数据或者登录状态异常,第一反应往往是“代码又出问题了”。很多时候真正的罪...

说出来你可能不信,如果你觉得51网不对劲,先从缓存管理查起

说出来你可能不信,如果你觉得51网不对劲,先从缓存管理查起

你打开页面觉得内容怪怪的、样式没更新、接口返回老数据或者登录状态异常,第一反应往往是“代码又出问题了”。很多时候真正的罪魁祸首不是代码本身,而是缓存:浏览器、CDN、反向代理、应用缓存、甚至服务端的 Redis/OpCache 都可能把“旧的世界”递给你。先做缓存排查,很多困扰能立刻消失。

为什么缓存会让人感觉“不对劲”

  • 缓存是为了提高速度、减轻后端压力,但如果缓存策略设计或失效机制出问题,用户会一直看到陈旧资源或错乱的状态。
  • 层级多:从用户浏览器、ISP DNS、CDN,到反向代理、应用缓存、数据库缓存,任何一层未及时刷新都能导致异常表现。
  • 某些缓存(如 Service Worker、App Cache、浏览器本地存储)更“粘”,不容易被常规刷新清掉。

快速排查流程(从简单到深入) 1) 浏览器端快速检查

  • 强制刷新:Ctrl+F5 / Shift+F5(Windows)或 Command+Shift+R(macOS)。
  • 无痕/隐身窗口打开,复现问题以排除普通缓存和扩展影响。
  • Chrome 开发者工具:F12 → Network → 勾选 “Disable cache”(注意:仅在 DevTools 打开时生效)。
  • 清除站点数据:F12 → Application → Clear storage → Clear site data(同时检查 Local Storage、IndexedDB、Service Workers、Cache Storage 并考虑卸载 service worker)。

2) DNS 和 本机缓存

  • Windows: ipconfig /flushdns
  • macOS(常用): sudo killall -HUP mDNSResponder
  • Linux(systemd): sudo systemd-resolve --flush-caches(或根据发行版使用 nscd 重启)
  • Chrome 专用: chrome://net-internals/#dns(可以清 DNS 缓存)以及 chrome://net-internals/#sockets(清 sockets)。

3) 使用 curl 和抓包检查响应头

  • 查看头部判断是否被缓存:curl -I -L https://你的域名/路径
  • 强制不使用缓存请求:curl -H "Cache-Control: no-cache" -I https://你的域名/路径
  • 关键头部看点:Cache-Control、Expires、ETag、Last-Modified、Age、Via、X-Cache、CF-Cache-Status(Cloudflare)等。Age 表示资源在缓存中存放的时间;X-Cache 或 CF-Cache-Status 可以直接告诉你是否命中缓存。

4) CDN / 反向代理(常见命中点)

  • 在 CDN(如 Cloudflare、Fastly 等)控制台尝试 Purge(清除缓存)或针对 URL/PATH 执行局部清理。
  • 检查 CDN 的缓存 TTL、缓存键(是否包含 cookies、query string)和是否缓存 HTML。
  • 如果使用 Nginx proxy_cache、Varnish 等,查看是否有正确的刷新策略(purge、ban),并检查缓存日志或状态命中率。

5) 服务端应用缓存与持久化缓存

  • Redis / Memcached:确认 key 是否被过期、是否有错误的命名导致旧数据一直被读到;必要时执行针对性的 delete 或 flush(慎用 flushall)。
  • 应用层缓存(如 Django cache、Spring Cache、Laravel cache):检查缓存键命名与版本策略,确认是否在部署时触发失效。
  • PHP 的 OpCache:如果代码更新但没有重启或刷新 opcache,会出现“代码没变”的表现。可以使用 opcache_reset() 或重启 PHP-FPM。

6) 前端构建与缓存失效(Cache busting)

  • 静态资源建议使用带 hash 的文件名(app.123abc.js),每次发布生成不同文件名,彻底避免旧资源被缓存。
  • 若无法改名,至少在 URL 上加版本号 ?v=20260220(虽然不如哈希彻底)。
  • 设置合理的 Cache-Control:对静态资源使用 long max-age + immutable(若文件名带 hash);对 HTML 使用 no-cache 或 must-revalidate,确保 HTML 能验证而不是长期缓存。

7) Service Worker / PWA 专门注意

  • Service Worker 会拦截网络请求并返回缓存内容,开发中常常忘记更新或 unregister。DevTools → Application → Service Workers → Unregister。
  • 清理 Cache Storage 中的缓存条目,确保 PWA 不在服务端更新后继续返回旧资源。

排查时的常用命令/工具汇总

  • Curl:curl -I -L https://domain,curl -H "Cache-Control: no-cache" -I https://domain
  • 浏览器:DevTools Network(Disable cache)、Application(清 Site Data、Service Workers、Cache Storage)
  • DNS flush:ipconfig /flushdns(Windows) / sudo killall -HUP mDNSResponder(macOS) / systemd-resolve --flush-caches(Linux)
  • 在线工具:webpagetest.org、GTmetrix、Pingdom、curl.trillworks.com(检查响应头)
  • 日志:检查后端 access log、CDN/缓存日志,找“Age”、“X-Cache”之类字段确认是否被缓存命中

常见“奇怪现象”与对应原因

  • 页面内容更新但用户仍看到老内容:CDN 或浏览器缓存未失效,或 HTML 被缓存;如果带有 Service Worker,优先检查它。
  • 接口返回旧数据:后端缓存(Redis/Memcached)或代理缓存;也可能是查询被错误缓存为全局结果(未按用户区分)。
  • 样式或 JS 显示错乱:静态资源被缓存但版本不匹配(HTML 指向新文件名但旧文件仍被 CDN 缓存),或 CSS/JS 部分更新导致兼容问题。
  • 登录/会话问题:Cookie 与缓存交互不当,某些缓存层缓存了带有用户信息的响应(避免缓存带有 Set-Cookie 的响应)。

长期解决策略建议

  • 约定清晰的缓存策略:静态资源使用文件哈希并设置长缓存,动态 HTML 设置可验证短缓存或 no-cache。
  • 部署时自动化清理:每次上线触发 CDN 局部清理或发布系统触发缓存失效 API。
  • 指定缓存键:CDN/反向代理不要忽略重要的 headers(如 Authorization、Cookie)作为缓存键,避免把带用户状态的页面当做公共缓存。
  • 增加可观测性:在响应头或日志里保留缓存相关字段(Cache-Control、Age、X-Cache),便于排查与统计。
  • 测试覆盖:上线前在不同网络、不同区域和无痕模式下验证资源是否如预期被替换或刷新。
  • 监控与告警:缓存命中率异常、Age 值非常大、CDN error rate 上升都可以作为告警触发点。

小结快速清单(用于立刻排查)

  1. 在本机按 Ctrl+F5 或用无痕窗口重试。
  2. DevTools → Network → Disable cache;检查 Network 的响应头。
  3. 检查是否存在 Service Worker,必要时 unregister 并清 Cache Storage。
  4. curl 查看 HTTP 头(Cache-Control、Age、ETag、X-Cache 等)。
  5. 清 DNS 缓存并尝试不同网络或设备。
  6. 到 CDN/反向代理控制面板执行 purge,查看缓存策略与 TTL。
  7. 检查后端 Redis/OpCache 等是否需要刷新。
  8. 部署后确保静态资源版本策略(hash)生效。