Vary来控制CDN的多版本缓存

CDN其实是一个缓存系统,那么这个缓存系统的key是跟什么相关呢?首先想到的就是URL,以及可以控制是否考虑URL上问号后面的参数,但有些时候这样是不够的,特别有如下两个场景:

1. 安卓、chrome(Google他们家的)都是支持webp的,而众所周知,苹果家的safari是不支持的。那么对于同样的请求,就需要根据不同的客户端返回不同格式的图片用于展示;

2. 各方面来看br是更适合于网络资源压缩的压缩算法,而老一些的客户端还是只支持gzip。那么对于同样的请求,就需要根据不同的客户端返回不同的压缩格式的数据;

针对这种,同样的请求,会有不同版本的缓存数据的情况,可以将各家CDN服务商分成三类:

1. 支持直接在后台设置缓存key需要考虑哪些http header在内,如:阿里云、aws

2. 不支持直接配置,但是支持http的Vary头来控制,这就需要有一定的后端能力了,如:百度云

3. 只能以url及参数作为缓存key,简单说就不支持这种优化需求,比如想要使用webp,就需要客户端自己做好检测来决定应该请求哪个url,如:七牛云

当然阿里云和aws也是CDN费用最贵的一档了,关于如何配置缓存key,可移步《阿里云和aws的CDN回源策略的缓存key配置》

这里说一下Vary对CDN缓存的控制,http返回的Vary header就是告诉CDN,如果哪个header发生变化了,那么这个返回结果可能就不对了。

对于上面的场景1,我们需要后端返回时带上Vary: accept,对于上面的场景2,后端返回时需要带上Vary: accept-encoding

很多时候,我们是通过nginx来直接服务于静态资源的访问,这时不涉及后端代码,那该如何配置nginx呢?重点如下:

gzip  on;
gzip_vary on;
gzip_proxied any; #ignore Via header
...

brotli  on;
...

gzip_vary就是用于添加Vary: accept-encoding头,这里的gzip_proxied需要额外注意,因为CDN是代理缓存,所以请求会带Via头过来,而nginx认为代理缓存不应该压缩,所以如果有Via存在,就算请求头里明示了支持gzip,也是不会进行压缩的。所以需要设置gzip_proxied。

brotli是谷歌提供的nginx扩展,默认就会带上Vary,也默认就会忽略掉Via,配置起来比较简单。

发表于 2022年02月17日 16:37   评论:0   阅读:1351  



回到顶部

首页 | 关于我 | 关于本站 | 站内留言 | rss
python logo   django logo   tornado logo