DTeam 技术日志

Doer、Delivery、Dream

巧用 cache-control: s-maxage 头优化CDN和浏览器缓存同步

冯宇 Posted at — Jun 22, 2021 阅读

浏览器和 CDN 之间缓存同步问题

今天我们已经非常普遍的使用 CDN 提供我们的静态网站和静态资源的访问。但是实际使用中会发现,通常存储后端资源发生变化之后,我们会尝试刷新 CDN。但是由于用户浏览器依旧保留旧资源,造成访问不一致的问题。本文我们将提供一些解决思路。

TL;DR 解决方案

在源后端的资源添加参考 header:

cache-control: max-age=0,s-maxage=604800

方案解释说明

理论上静态资源最好能做到cache busting,即资源一旦发生变更,那么文件名应该变更。但是实际使用中总会有部分文件难以做到 cache busting,如index.html等。如果这一类文件较为频繁的更新,我们可能希望用户浏览器访问的时候总能拿到最新的资源。但又不希望 CDN 缓存击穿,所以可以用上s-maxage这个参数。

浏览器通常会看cache-control: max-age=xxx 这个参数,决定在某一段时间内本地缓存是新鲜的,不会向服务器发起请求。

有关详情可以参考之前的文章: HTTP Header 中的黑科技#缓存(通过 header 控制) 部分

CDN 通常也会遵循这个头,如果仅仅设置cache-control: max-age=0,固然每次浏览器会向 CDN 请求验证资源新鲜度,但是也会造成 CDN 每次都回源验证,会引起缓存击穿的问题。而静态资源通常更新并不频繁,我们可能会期望浏览器仅仅找 CDN 验证新鲜度就够了,CDN 不需要回源。对于这种场景,在cache-control头中添加s-maxage参数就够了。这个参数 CDN 通常会处理,优先级比max-age高。这样就实现了我们的需求。

NOTE: 最理想的方案仍然是 cache busting。此方案仅适用于实在无法做到的静态资源。对于一些不需要太重视新鲜度问题的资源,仅仅max-age参数就够了,这样可能尽可能在浏览器段缓存资源,减少 CDN 的请求流量。


友情链接


相关文章