Http标准请求
例如客户端发送以下请求头(它表示可以支持采用gzip,deflate,br压缩过的资源):
浏览器的响应头可能是这样的(它表示内容已经进行了gzip压缩):
于是,服务器会根据请求头信息,返回相应的内容(已gzip压缩)给客户端,这是最直接的请求服务,也是最理想的,客户端要什么,服务器就发什么
现实往往是不尽人意的,客户端与服务端中间会有大量的公共缓存代理服务器(如CDN),这就存在一个问题了,CDN怎么根据请求头去决定给客户端发送什么样的内容呢?即便CDN会像服务端(源站)那样响应有Content-Encoding,难免会出现CDN“出小差”的情况(不能正确检测Content-Encoding或者忽略响应头中的Content-Encoding),于是乎浏览器只能拿到未压缩版本,解压渲染失败页面显示一堆乱码。为了解决这个问题,下面vary出场!
“Vary:Accept-Encoding”标头
指定“Vary: Accept-Encoding”标头可告诉代理服务器(CDN)缓存两种版本的资源:压缩和非压缩,这有助于避免一些公共代理不能正确地检测Content-Encoding标头的问题,这是官方说明。
官方的说明解释的很清楚,为了能让CDN分别缓存不同版本的内容,以满足不同类型(压缩或者未压缩)的请求,需要指定“Vary: Accept-Encoding”到CDN。比如我想要未压缩版本的,CDN却给我提供压缩版本的,有些浏览器不支持解压缩功能,就没法做进一步渲染,反之亦然。
解决方案,源站发送“Vary: Accept-Encoding”!
下面会用一则真实案例说明之
案 | 例欣 | 赏
“海外访问白板”,一句话打破了早晨的宁静
运营GG以迅雷不及掩耳之势作出响应
客户已经有点着急了,看到这里咱不能慌,稳住阵脚
作为一名合格的运营GG,此时应该故作镇定,并安抚客户,同时应尽快找到问题的原因
问题初见雏形,经过运营GG深入浅出的分析,发现页面内容是通过php动态文件进行解析的,而CDN不具备缓存动态内容的能力。虽然最后的事实证明,这并不是问题的真正原因,姑且先这样给客户解释,一名合格的运营GG需要掌握缓兵之计!
根据客户的反馈,图片等静态内容确实已经缓存在CDN上了
至此,可以排除php调用的原因,运营GG继续剥丝抽茧
在解决问题的过程中,需要仔细聆听客户的反馈,也许会事半功倍
前面的折腾已经花费了不少时间,客户的耐心似乎已经到了极限!
时间一分一秒的过去了,业务已经严重遭受到影响。解决问题,刻不容缓!
真相逐渐浮出水面!
“使用了不统一的页面编码导致”,说白了就是浏览器想要压缩版,CDN给了未压缩版
结合之前D站出现的类似情况(首页白屏),运营GG大胆猜测,细心求证
这里要说明下,这个case使用了二级源站,即真正源站(一级源站)和代理源站(二级源站)
Client-->CDN-->代理源站-->真正源站,这是各网元的大致关系,代理源站会从真正源站拿到内容,而真正源站会响应vary header到代理源站,于是乎代理源站就能成功显示页面。但是代理源站这家伙没有透传或者响应这个vary header给CDN,CDN拿不到这个标头就没法给客户端提供他们所需要的真正版本内容。
所以把代理源站去掉,CDN直接对接真正源站就正常了。于是就有了上面“我们刚才试了把源站改成真正的源站,就可以访问了”的说法
随后,客户在代理源站上配置vary header发送到CDN
运营GG清理CDN缓存,大家都在紧张地等待验证的结果
“上下同欲者胜”,这个结果似乎是意料之外,也是情理之中!
小编无法描述当时运营GG的心情,我想“出来了”这仨字应该承载了不少喜悦
最终,以客户的感受结束这场风波,相信运营GG此刻的感受也是如出一辙
对于任何事情,小编都这么认为,“凡事尽力而为,而后顺其自然”
就像运营GG这次“尽力而为”,当再次遇到类似的问题时,解决方案也就“顺其自然”了
“人生何处没有坑,躲过一坑算一坑!”
如有兴趣可关注公众号:国际CDN讲堂