缓存策略与回源策略必须作为同一套流量治理体系的两面来设计,任何只调缓存参数或只改回源规则的优化,都容易在线上暴露命中率虚高、回源雪崩或成本失控的问题。
网站的性能优化里,缓存和回源经常被当成两件事,一个团队调缓存头,另一个团队管源站,中间用CDN的默认配置连接,这种分工在流量平稳时看不出毛病,一旦遇到大促、热点更新或攻击流量,割裂设计就会让两个策略互相打架,下面从区别、命中率、回源失败和穿透场景拆开讲,但每个场景最终都会回到同一个结论:缓存策略和回源策略要一起定。
缓存策略和回源策略有什么区别
这两个词听起来像一回事,实际作用点不同。
- 缓存策略决定资源在离用户最近的节点上保存多久、以什么条件复用。
- 回源策略决定缓存没命中或缓存过期后,请求以什么方式回到源站、回源失败后怎么办。
用仓库比喻:缓存是门店货架,回源是后仓补货,货架摆多少货、多久下架,是缓存策略,货架空了以后,店员按什么频率去后仓取货、后仓没货时怎么答复顾客,是回源策略,分开设计时,门店可能把货架空得太满,后仓却按小时补货,结果热销品一断货,顾客全挤到后仓门口。
行业内有一个常见误区:认为只要源站吐出的Cache-Control写得好,CDN就会自动省事,实际源站的缓存头只解决“资源可缓存多久”,不解决“缓存失效瞬间的并发回源怎么收敛”,业内专家指出,相当一部分回源雪崩的根因不在源站性能,而在缓存过期窗口与回源并发策略没有对齐。
网站缓存命中率低怎么优化
很多站长发现CDN后台的缓存命中率长期偏低,第一反应是延长缓存时间,这个操作方向没错,但如果不看回源策略,命中率可能纹丝不动。
先看一个具体场景:某资讯App把新闻封面图缓存设为7天,源站也返回了max-age=604800,但CDN命中率仍不理想,排查后发现,客户端每次请求都带了一个随机的bust参数,导致CDN认为每个URL都是新资源,回源率被拉高,这种情况不是缓存时间不够,而是回源策略里的缓存键规则没有和源站URL约定对齐。
优化命中率时,建议按以下顺序操作:
- 用浏览器开发者工具看源站响应头,确认Cache-Control是否真实存在、是否私有值。
- 用
curl -I https://源站域名/资源路径检查响应头,对比CDN回源时收到的头是否一致。 - 检查CDN控制台的缓存键配置,看是否忽略了无关查询参数。
- 检查Vary头是否包含User-Agent,如果包含,会让同一资源按不同终端类型存多份,命中率被稀释。
- 检查首页或接口是否错误地返回了
Cache-Control: no-cache,这会让边缘节点每次都要回源确认。
静态资源缓存多久合适
静态资源的缓存时长不能拍脑袋定,行业共识认为,应该按回源成本分层设置。
| 资源类型 | 建议缓存时长范围 | 回源策略配合 |
|---|---|---|
| 带指纹的JS/CSS | 一年 | 文件更新即换URL,回源只发生在新文件首次请求 |
| 图片/字体 | 7天到一年 | 图片可长缓存,但需保证源站存储稳定 |
| HTML主文档 | 不缓存或短期缓存 | 用CDN回源时源站实时生成,配合协商缓存 |
| 接口响应 | 按业务时效设置 | 对可容忍旧数据的接口,用stale-if-error兜底 |
表格里的时长是常见实践区间,不是硬性标准,核心思路是:越不容易变、回源成本越高的资源,越要拉长缓存并设计好回源兜底,例如JS文件带内容指纹后,一年缓存也不会出现用户拿到旧代码的问题,反而能大幅降低回源流量费用。
CDN回源失败常见原因
回源失败经常被简单归为“源站挂了”,实际原因要复杂得多。
- 回源Host配置错误:CDN回源时携带的Host头和源站证书不匹配,导致SSL握手失败。
- 源站防火墙或安全组把CDN回源IP误封,特别是华南节点更换IP段后容易出现。
- 源站响应时间超过CDN回源超时阈值,连接被边缘节点主动断开。
- 源站返回5xx,而CDN没有配置错误缓存,请求直接穿透到故障源站。
- 回源带宽跑满,源站出口拥塞,健康检查失败后节点摘除。
这些情况如果只优化缓存,治标不治本,比如源站偶发超时,可以把CDN回源超时阈值从5秒调到10秒,但更稳妥的做法是同时给缓存配置stale-if-error,让边缘节点在回源失败时先吐旧缓存,避免用户直接看到错误页,这就是缓存策略与回源策略作为一个整体设计的好处。
回源超时与缓存兜底配置的配合
在Nginx源站上,可以这样给静态文件加一个带兜底的缓存头:
location ~ .(jpg|png|css|js)$ {
add_header Cache-Control "public, max-age=86400, stale-if-error=3600";
}
这行配置告诉边缘节点:资源正常缓存一天;如果回源时源站出错,允许再使用过期一小时的旧资源,这个动作同时调整了缓存有效性和回源失败时的可用性,单独改回源超时或单独加缓存头都做不到这个效果。
高并发下缓存穿透解决方案
缓存穿透、击穿、雪崩三个词经常一起出现,但本质不同。
- 穿透:请求一个根本不存在的数据,缓存和源站都没有,导致请求穿过缓存直击源站。
- 击穿:某个热点数据缓存过期,大量并发同时回源。
- 雪崩:大量缓存在同一时间过期,源站压力瞬时升高。
如果只从缓存角度解决穿透,常见做法是缓存空值,但空值缓存只能挡住不存在的key,挡不住大量不同key的穿透,整体视角下的方案是把回源策略加进来:
- 在源站入口对高频不存在的路径做快速拒绝,比如返回404但不查数据库。
- 在CDN边缘配置针对404的短时缓存,让同一路径的后续请求直接被节点拦截。
- 对无法判断的请求,用回源限流保护源站,而不是让所有请求都冲到后端。
- 对热点key的过期时间加入随机偏移,避免同一秒全部失效。
从回源策略做入口限流,而不是只加缓存,是应对穿透的关键,CDN边缘节点本身就有连接数和请求数限制,把限流阈值设在源站可承受的范围内,缓存才有机会发挥缓冲作用。
整体设计的落地顺序
把缓存策略和回源策略当成一个整体,落地时可以从三个动作开始。
- 梳理资源分类:把静态资源、半动态接口、个性化内容分开,每类资源对应不同的缓存时长和回源规则。
- 对齐缓存键:确保CDN缓存键、源站URL参数、业务更新机制三者一致,避免同一个文件被当成多个资源。
- 配置兜底路径:给核心资源设置stale-if-error或类似机制,让回源失败时用户还能拿到旧内容。
这套动作不需要同时做完,但每做一步都要同时检查缓存参数和回源行为,只改一端,另一端迟早会以报警或投诉的形式暴露问题。
缓存策略决定资源离用户多近,回源策略决定拿不到资源时怎么办,两者本来就该是一套方案的两个执行层,分开看只会让优化互相抵消。
Q&A:缓存策略和回源策略如何整体设计
问:缓存策略和回源策略有什么区别?实际优化时先改哪个?
答:缓存策略管资源在各节点的保存时长和复用条件,回源策略管缓存未命中时请求如何回到源站,没有固定先后顺序,正常做法是先梳理资源分类,再同时调整缓存头和回源超时、缓存键等参数,只先改缓存,容易掩盖回源侧的问题。
问:网站缓存命中率低怎么优化回源参数?
答:先确认CDN缓存键是否与源站返回的URL规则一致,重点检查查询参数、Vary头和回源Host,可以通过curl对比源站响应头和CDN回源响应头,如果发现源站返回的Cache-Control被边缘节点覆盖或忽略,需要检查CDN的缓存规则优先级。
问:高并发下缓存穿透解决方案有哪些?
答:常用组合是缓存空值、布隆过滤器、入口限流和404短时缓存,缓存空值挡住重复的不存在key,布隆过滤器在源站前拦截大部分穿透请求,CDN边缘对404做短时缓存减少回源量,源站入口限流保证后端不被瞬时流量击穿,这套组合必须把缓存和回源策略放在一起配置,单独使用其中一项很难应对高并发下的穿透压力。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/642428.html




