关于91网,我把缓存管理讲清楚后,很多问题都通了(别说我没提醒)

打开缓存管理的那一刻,许多看似复杂的问题瞬间变得有迹可循:页面不更新、图片老是走老版本、接口响应忽快忽慢、带宽浪费、Redis/缓存层频繁被抖开……把缓存的“职责分工”和“失效策略”理清楚后,排查与优化都变得简单多了。下面把我在91网落地的实践和通用方法写清楚,按步骤去做,能帮你把绝大多数缓存相关问题解决掉。
一、先把缓存的几类讲清楚(要分清角色)
- 浏览器缓存(客户端):由浏览器根据响应头缓存静态资源或页面片段,减少重复请求。
- CDN缓存(边缘缓存):把静态资源或可缓存响应放到离用户更近的节点,减少原站流量。
- 反向代理/缓存层(如Nginx、Varnish):位于应用前用于缓存动态渲染结果或静态文件。
- 应用内缓存(Redis、Memcached):缓存数据库查询、计算结果或会话数据等。
- 离线缓存(Service Worker):针对PWA做更灵活的离线访问和精细化缓存策略。
二、缓存目标与原则(不要把所有东西都当“长期缓存”)
- 静态可变更资产(JS/CSS/图片等):可以长期缓存,采用文件名指纹(content hash)做版本管理。
- HTML 页面或动态内容:通常短缓存或不缓存(通过协商缓存让浏览器/CDN去校验),或用 stale-while-revalidate 优化感知速度。
- API 接口数据:根据业务一致性需求设置TTL,关键数据短TTL或强制回源。
- 敏感/用户私有数据:绝对不要让公共CDN或客户端长期缓存(Cache-Control: private/no-store)。
三、HTTP缓存头如何设置(直接上可用示例)
- 静态资源(带版本号的文件)
Cache-Control: public, max-age=2592000, immutable
说明:30天,immutable适合文件名包含hash的文件
- 页面HTML(可用协商缓存)
Cache-Control: no-cache, must-revalidate
或者:Cache-Control: max-age=0, must-revalidate
搭配ETag或Last-Modified返回304,节省带宽同时保证内容及时性
- 敏感响应
Cache-Control: private, no-store, no-cache
- 想做无感刷新体验(stale-while-revalidate)
Cache-Control: public, max-age=60, stale-while-revalidate=30
说明:用户在TTL过后允许看到陈旧内容但后端异步刷新,加速体验
四、常用服务器/代理配置片段(Nginx示例)
- 静态资源长期缓存(带文件hash)
location ~* .(?:css|js|jpg|jpeg|png|gif|svg|webp|woff2?)$ {
expires 30d;
addheader Cache-Control "public, max-age=2592000, immutable";
accesslog off;
}
- HTML做协商缓存
location / {
tryfiles $uri $uri/ /index.html;
addheader Cache-Control "no-cache, must-revalidate";
}
- 强制禁止某路径被CDN缓存(通过响应头)
location /api/private/ {
add_header Cache-Control "no-store, no-cache, private";
}
五、CDN配置要点(Cloudflare 等)
- 让CDN尊重源站Cache-Control,或在CDN层通过规则覆盖。
- 静态文件在CDN层设置长缓存、并通过文件名版本管理做更新。
- 动态页面一般设置短缓存或使用“按路径/按参数缓存规则”。
- 利用标签/分组化清理(purge by tag)方便批量失效;如果没有,保证能以API方式按文件名/路径清理。
- 注意缓存键:是否包含Query String、Cookie、Accept-Encoding 等会影响缓存命中。
六、应用缓存(Redis/Memcached)实战建议
- Key 设计:统一前缀(env:service:entity:id:version),便于清理和统计。
- TTL 策略:热点数据短TTL+后台异步更新,冷数据长TTL或无TTL。
- Eviction 策略:生产选择 LFU 或 LRU,容量预留要足够,避免频繁回源。
- 缓存穿透/击穿/雪崩
- 穿透:对不存在数据加布隆过滤器或缓存空结果短期防打穿。
- 击穿:热点key使用互斥锁、请求合并或提前加缓存。
- 雪崩:分散大面积过期时间(加随机Jitter),或设置预热机制。
- 持久化:缓存一般关闭持久化,但要根据业务考虑数据恢复策略。
七、版本控制与缓存失效策略(最常用也最可靠)
- 文件名版本化(content-hash):每次发布产物变更都会生成新文件名,CDN/浏览器自动拉取新资源。
- Query string 版本化(不推荐对CDN友好度较低):/app.js?v=20260219
- 强制清理:使用CDN API或Edge清理接口按路径/通配符清除缓存。
- 后端逻辑版本:接口返回的资源里携带version字段,客户端做对比后决定是否缓存/刷新。
八、诊断与排查流程(按步骤)
1) 用浏览器DevTools查看Network面板,感知是否命中(200/304)、Cache-Control、Expires、ETag、Age、cf-cache-status/x-cache 等头信息。
2) 用curl检查原始响应头:
curl -I https://your.site/path/file.js
3) 观察CDN响应头(X-Cache、CF-Cache-Status等),判断是HIT还是MISS。
4) 若发现旧文件仍被使用,确认:
- 文件名是否改变(content hash)
- CDN是否做了缓存覆盖规则
- 浏览器是否受Service Worker影响
5) 若Redis频繁miss或命中率低,查看info命令里keyspace和eviction信息,定位是否内存不足或key设计问题。
6) 日志与监控:统计缓存命中率、回源流量、TTL分布、热门key列表。
九、常见问题与解决方法对照表
- 问题:页面更新后用户仍看到旧资源
解决:确保静态资源走文件名指纹或CDN purge;检查Service Worker是否拦截。
- 问题:API响应被CDN缓存导致数据不一致
解决:为该接口设置Cache-Control: no-cache或private,或在CDN配置中排除该路径。
- 问题:Redis内存突降,频繁回源
解决:检查eviction、增加内存或优化缓存键与TTL、使用更合适的LRU/LFU策略。
- 问题:大量304响应仍然造成高负载
解决:考虑使用更长的静态缓存,或启用CDN边缘缓存来减少到源站的复用请求;优化协商缓存逻辑。
十、部署前的检查清单(发布前必须过一遍)
- 静态文件是否带hash并可被CDN长期缓存?
- HTML/动态接口Cache-Control是否按业务需求设置?
- CDN缓存规则是否覆盖了期望路径?
- Service Worker是否在新版本上做了合适的策略和更新逻辑?
- Redis/缓存层内存和Eviction配置是否合理?
- 是否有自动化的CDN缓存清理或发布脚本支持?
十一、一些实践小技巧(节省流量并提升感知速度)
- 将大图做WebP/AVIF并使用responsive images,让CDN缓存更高效。
- 对非关键JS做异步/延迟加载,减少首屏资源。
- 对接口响应启用gzip/flate或Brotli压缩,降低带宽与缓存体积。
- 在低风险内容使用 stale-while-revalidate:快速响应 + 后台刷新。
- 监控缓存命中率和回源比例,把热点资源进一步优化为“边缘冷启动友好”。
结语
缓存不是万能,但分清职责、按类型设策略、做好版本化和清理手段后,很多看起来“偶发”的问题都会迎刃而解。在91网的实践里,从“谁该缓存什么、怎么失效、如何排查”这三件事先搞清楚,就能把绝大多数性能和一致性问题锁死。如果你把上面清单一项项跑一遍,遇到具体场景我可以继续帮你深挖配置示例或诊断思路。需要我给出91网当前某个目录的具体Nginx/Cloudflare配置样板吗?
本文标签:#关于#我把#缓存
版权说明:如非注明,本站文章均为 暗网探秘与隐私保护平台 原创,转载请注明出处和附带本文链接。
请在这里放置你的在线分享代码