关于91网,我把缓存管理讲清楚后,很多问题都通了

关于91网,我把缓存管理讲清楚后,很多问题都通了

引言 近日在优化91网的过程中,我把整套缓存体系从头梳理并明确了管理规则,结果很多长期困扰我们的问题迎刃而解——页面不一致、峰值时源站奔溃、静态资源更新慢、调试上线频繁互相影响等。下面把我整理的方法和实战细节写出来,便于复用和传播,也方便你直接在网站上发布、收藏或分享给团队。

缓存基础:先把概念讲清楚

  • 缓存层级:浏览器缓存(client)、CDN(edge)、反向代理(如Nginx/Varnish)、应用内缓存(内存/Redis)、数据库缓存。每层都有不同的粒度、TTL和失效方式。
  • 两种基本策略:强制缓存(Cache-Control: max-age、immutable、Expires)和协商缓存(ETag、Last-Modified + 304)。
  • 缓存键(cache key):决定相同请求是否命中缓存。通常基于 URL、查询参数、Host、Headers、Cookies 等构成。CDN/代理一般允许自定义。
  • 缓存失效:主动(Purge/Surrogate-Key)和被动(TTL 到期、协商校验)。主动失效要靠接口和体系支持,被动失效要靠合理的 TTL 和 revalidation 策略。

我们之前遇到的典型问题(列举现实场景)

  • 页面A上线后,部分用户还能看到旧版本,刷新也不稳定(浏览器+CDN缓存配置冲突)。
  • 高并发促销时段,源站瞬间被击穿(缓存未覆盖热点或缓存失效策略不当)。
  • 静态资源更新需要改名或手动清理多层缓存,流程复杂易出错。
  • 针对用户登录态或个性化内容,缓存策略混淆导致敏感数据被缓存到公共层。
  • CDN配置里忽略了某些Header或Cookie,导致资源缓存分散、命中率低。

我采取的逐步方法(落地可操作) 1) 全面审计(从“现状”开始)

  • 用 curl -I、浏览器 DevTools、CDN 控制台和访问日志记录每个资源的响应头(Cache-Control, ETag, Age, Via 等)。
  • 列出所有可能被缓存的路径和页面,标注“是否可缓存”“缓存等级(静态/半静态/动态)”“失效时机”。

2) 按资源波动性分类并定义策略

  • 静态资源(图片、JS、CSS):采用文件名哈希(content hash),Cache-Control: public, max-age=31536000, immutable。
  • 半静态(配置、模板):中等 TTL(几分钟到几小时),可使用 surrogate-keys 方便批量清理。
  • 动态/个性化内容:不在公共 CDN 缓存或缓存短 TTL,使用边缘侧逻辑做差异化(Edge-side includes、Edge Workers)或基于用户标识的缓存键。

3) 统一并修正响应头

  • 对静态资源强制:Cache-Control: public, max-age=31536000, immutable。
  • 对可协商的资源:提供 ETag 或 Last-Modified,并结合合理的 max-age,避免每次都回源。
  • 对敏感或绝对不能缓存的页面:Cache-Control: no-store, no-cache, must-revalidate(根据需要选择)。

4) 静态资源版本化(必须做)

  • 构建时把内容哈希加入文件名(app.abc123.js)。上线时不再依赖清理缓存。
  • 对 HTML 主文件和模板采用较短 TTL,并在部署流程中更新引用到新哈希的静态资源。

5) CDN 与缓存键的优化

  • 确定缓存 key:对静态资源忽略 Cookie、Authorization;对需要区分 UA 或 Accept-Language 的资源把对应 Header 加入 key。
  • 使用 CDN 的 surrogate-key/Tag 功能,按业务模块或路径打标,部署/回滚时可按 tag 批量清理。
  • 设置分级缓存(edge + origin shield)减少 origin 压力。

6) 防止缓存雪崩与击穿

  • 对高并发热点使用互斥锁、request coalescing、或设置随机化 TTL(TTL jitter)。
  • 在缓存失效前使用 stale-while-revalidate,让边缘在回源时仍可返回旧内容,降低回源峰值。
  • 对关键数据设置二级缓存(应用内 + CDN),并为后端设置降级逻辑。

7) 动态内容与个性化策略

  • 对用户私有数据做 no-cache/no-store,或使用不同的缓存空间(按用户 token 做 key)并严格避免公开层缓存。
  • 如果页面大部分是公共的、只有小块个性化,可采用 Edge Side Includes(ESI)或客户端异步请求个性化区域。

8) 自动化与运维流程

  • 在 CI/CD 中加入缓存相关动作:静态资源哈希、部署后触发 CDN 刷新(按 tag),记录变更日志。
  • 提供一键回滚或回源开关(当缓存逻辑出问题时能快速切换到“绕开缓存”的临时方案)。

监控与量化指标(不做监控就无法优化)

  • 关键指标:缓存命中率、Origin 请求数、边缘带宽、P95/P50 页面加载时间、错误率。
  • 告警规则:源站请求短时间暴增、缓存命中率急跌、特定资源 404/500 激增。
  • 用 Grafana/Prometheus 或 CDN 自带 Analytics 做可视化,按业务维度分拆指标(首页、静态资源、API等)。

实战小例子(常用命令)

  • 查看响应头:curl -I https://91.example.com/static/app.js
  • 强检 header 示例:Cache-Control: public, max-age=31536000, immutable
  • 协商缓存示例:ETag: "abc123", 当客户端下次请求带 If-None-Match 时,源站可返回 304。

常见症状与快速排查清单

  • 症状:用户看不到最新内容 检查点:浏览器 DevTools Network 看是否有 304 / Age / Cache-Control;CDN 是否有旧对象;是否需静态资源哈希。
  • 症状:高并发导致源站崩溃 检查点:缓存命中率、TTL 设置、是否有热点未被缓存、是否存在未处理的缓存击穿。
  • 症状:个性化信息被错误缓存 检查点:响应是否含有 Set-Cookie 或 Authorization 被 CDN 纳入缓存 key;是否使用了 no-store。
  • 症状:CDN 缓存分散、命中率低 检查点:缓存键是否包含不必要的 Header/Cookie/Query 参数,是否需要统一清理策略。

我在91网的效果(可量化改进示例)

  • 缓存命中率从 30% 提升到 80% 以上(典型目标),源站请求量显著下降,峰值稳定许多。
  • 首屏加载时间明显降低,用户体验提升,页面可用性在高并发时段稳定。
  • 部署和回滚流程更清晰,静态资源无需每次手动清缓存,团队协作效率提高。

结语(给出可直接执行的下一步) 如果你正在为站点的“看不见的慢”和“不可靠的缓存”头疼,建议先做三件事:1)全面审计当前缓存头和 CDN 行为;2)把静态资源做哈希并设置长期缓存;3)为动态/个性化内容定义明确的缓存边界。按上面步骤逐条落实,你会发现系统稳定性和运维效率都能快速改观。