差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
第三方cdn_gzip压缩避坑指引 [2016/10/20 22:17]
ywjt [HTTP压缩相关头部]
第三方cdn_gzip压缩避坑指引 [2016/10/21 17:51] (当前版本)
ywjt
行 1: 行 1:
- ​--- ​//​[[ywzysq@4399.com|ywjt]] 2016/10/20 20:47//+//​[[ywzysq@4399.com|ywjt]] 2016/10/20 20:47//
 ====== 第三方CDN GZIP避坑指引 ====== ====== 第三方CDN GZIP避坑指引 ======
-===== 背景信息 =====+===== 背景信息 =====
 在周期性对商业CDN频道进行巡检的过程中,偶然发现浏览器发送了一个压缩请求,请求的是某个频道上的一个JS文件,而CDN节点竟然返回的是明文的JS内容。源机采用的是nginx作为web服务器,已经确认该频道的源机配置了对JS文件的GZIP压缩,且直接向源机发送浏览器请求,响应的的确是GZIP文件。\\ 在周期性对商业CDN频道进行巡检的过程中,偶然发现浏览器发送了一个压缩请求,请求的是某个频道上的一个JS文件,而CDN节点竟然返回的是明文的JS内容。源机采用的是nginx作为web服务器,已经确认该频道的源机配置了对JS文件的GZIP压缩,且直接向源机发送浏览器请求,响应的的确是GZIP文件。\\
 \\ \\
-经过跟其他频道源机对比后,发现该频道的源机没有配置Gzip Vary的头部。而商业CDN在源机没有给出明确的Vary:​ Accept-Encoding头部的情况下,直接忽略了客户端请求的Accept-Encoding头。全部把数据明文发送给了用户。也就是不管请求的是压缩的还是非压缩的数据,CDN节点全部返回了明文,未压缩的数据。+经过跟其他频道源机对比后,发现该频道的源机没有配置Gzip Vary的头部。而商业CDN在源机没有给出明确的Vary:​ Accept-Encoding头部的情况下,直接忽略了客户端请求的Accept-Encoding头。全部把数据明文发送给了用户。也就是不管请求的是压缩的还是非压缩的数据,CDN节点全部返回了明文,未压缩的数据。\\ 
 +\\ 
 +<color red>​而对于文本内容居多的CDN频道,数据压缩传输和明文传输两者的CDN带宽差异巨大,一般超过30%。因此有必要结合实际的业务需求,对CDN和源机配置进行参数调优,避免CDN带宽的浪费。</​color>​
  
-===== 概念解析 ===== +===== 概念解析 ===== 
-==== HTTP压缩简介 ====+==== HTTP压缩简介 ====
 HTTP压缩是指在web服务器和浏览器之间压缩传输数据的方法,HTTP采用通用的压缩算法,例如gzip,来压缩web服务器和浏览器之间交互的数据,这样能够大大减少网络传输的数据路,提高了浏览器的加载速度,当前也会带来额外的服务器性能开销。以现代服务器来说,HTTP压缩所带来的好处远大于服务器性能开销所带来的成本。 HTTP压缩是指在web服务器和浏览器之间压缩传输数据的方法,HTTP采用通用的压缩算法,例如gzip,来压缩web服务器和浏览器之间交互的数据,这样能够大大减少网络传输的数据路,提高了浏览器的加载速度,当前也会带来额外的服务器性能开销。以现代服务器来说,HTTP压缩所带来的好处远大于服务器性能开销所带来的成本。
  
-==== HTTP压缩相关头部 ====+==== HTTP压缩相关头部 ====
 在http数据交互过程中,包括请求头部和响应头部,一般涉及到3个头部 在http数据交互过程中,包括请求头部和响应头部,一般涉及到3个头部
 请求:Accept-Encoding 请求:Accept-Encoding
 响应:Content-Encoding 响应:Content-Encoding
 响应:Vary 响应:Vary
-=== Accept-Encoding ===+=== Accept-Encoding ===
 **请求头示例** **请求头示例**
 {{ :​1.png?​nolink |}} {{ :​1.png?​nolink |}}
行 35: 行 37:
   - 如果有多个Encoding同时匹配,​ 按照q值顺序排列(从大到小)   - 如果有多个Encoding同时匹配,​ 按照q值顺序排列(从大到小)
  
-注意:+:!:注意:
  
-  * 普通列表项目大部分HTTP1.0的客户端无法处理q值+  * 大部分HTTP1.0的客户端无法处理q值
   * 上面只是列出了web服务器的通用处理规则,实际规则跟web服务器的具体实现有关   * 上面只是列出了web服务器的通用处理规则,实际规则跟web服务器的具体实现有关
  
-=== Content-Encoding ===+=== Content-Encoding ===
 **响应头示例** **响应头示例**
 {{ :​2.png?​nolink |}} {{ :​2.png?​nolink |}}
 Content-Encoding表明响应的实际编码方式,例如响应头是content-encoding:​gzip,则表明该响应的实际编码方式是gzip编码。 Content-Encoding表明响应的实际编码方式,例如响应头是content-encoding:​gzip,则表明该响应的实际编码方式是gzip编码。
  
-注意:+:!:注意:
  
   * 普通列表项目如果是明文传输的,则响应头一般无Content-Encoding该头部   * 普通列表项目如果是明文传输的,则响应头一般无Content-Encoding该头部
  
  
-=== Vary: Accept-Encoding ===+=== Vary: Accept-Encoding ===
 **响应头示例** **响应头示例**
 {{ :​3.png?​nolink |}} {{ :​3.png?​nolink |}}
行 58: 行 60:
 例如:响应头Vary:​ Accept-Encoding,则意味着CDN节点除了以请求url作为hash key之外,还会将Accept-encoding也作为key,那么对于Accept-encoding:​gzip和Accept-encoding:​ deflate这两个请求会缓存两个缓存副本到cdn节点上。\\ 例如:响应头Vary:​ Accept-Encoding,则意味着CDN节点除了以请求url作为hash key之外,还会将Accept-encoding也作为key,那么对于Accept-encoding:​gzip和Accept-encoding:​ deflate这两个请求会缓存两个缓存副本到cdn节点上。\\
  
->​注意:Vary:​ Accept-Encoding会导致CDN节点缓存多份副本,会降低缓存空间,个别小的CDN提供商可能采用gzip整形的方式,即统一将encoding整合成gzip和非gzip类型,这样CDN节点一般只会缓存两份副本。 
  
-===== 请求流程 =====+:​!:​注意: 
 +  * 普通列表项目Vary:​ Accept-Encoding会导致CDN节点缓存多份副本,会降低缓存空间,个别小的CDN提供商可能采用gzip整形的方式,即统一将encoding整合成gzip和非gzip类型,这样CDN节点一般只会缓存两份副本。 
 + 
 +===== 请求流程 =====
 {{ :​4.png?​nolink |}} {{ :​4.png?​nolink |}}
   - 浏览器发送Http request 给Web服务器, ​ request 中有Accept-Encoding:​ gzip, deflate。 (告诉服务器, 浏览器支持gzip和deflate压缩)   - 浏览器发送Http request 给Web服务器, ​ request 中有Accept-Encoding:​ gzip, deflate。 (告诉服务器, 浏览器支持gzip和deflate压缩)
行 66: 行 70:
   - Web服务器通过Gzip,来对Response进行编码, 编码后header中有Content-Type和Content-Length(压缩后的大小), 并且增加了Content-Encoding:​gzip. ​ 然后把Response发送给浏览器。   - Web服务器通过Gzip,来对Response进行编码, 编码后header中有Content-Type和Content-Length(压缩后的大小), 并且增加了Content-Encoding:​gzip. ​ 然后把Response发送给浏览器。
   - 浏览器接到Response后,根据Content-Encoding:​gzip来对Response 进行解码。 获取到原始response后, 然后显示出网页\\   - 浏览器接到Response后,根据Content-Encoding:​gzip来对Response 进行解码。 获取到原始response后, 然后显示出网页\\
-注意:如果web服务器有配置gzip vary,那么响应头中也会显示Vary:​ Accept-Encoding头部,该头部对CDN缓存非常重要,如果要使用CDN在源站开启gzip的同时一定要开启gzip vary。否则CDN节点无法正常的处理请求头的Accept-Encoding,可能会产生混乱(例如:浏览器请求的是gzip的,结果cdn节点返回的明文的)。+:!:注意: 
 +  * 普通列表项目如果web服务器有配置gzip vary,那么响应头中也会显示Vary:​ Accept-Encoding头部,该头部对CDN缓存非常重要,如果要使用CDN在源站开启gzip的同时一定要开启gzip vary。否则CDN节点无法正常的处理请求头的Accept-Encoding,可能会产生混乱(例如:浏览器请求的是gzip的,结果cdn节点返回的明文的)。
  
  
-===== 设置方法 =====+===== 设置方法 =====
 常用的web服务器包括apache和nginx,简单介绍这两种web服务器的http压缩配置参数。 常用的web服务器包括apache和nginx,简单介绍这两种web服务器的http压缩配置参数。
-====apache配置gzip压缩====+==== apache配置gzip压缩====
 编译mod_deflate模块,并且在配置文件中加载 编译mod_deflate模块,并且在配置文件中加载
 <​code>​LoadModule deflate_module modules/​mod_deflate.so</​code>​ <​code>​LoadModule deflate_module modules/​mod_deflate.so</​code>​
行 84: 行 89:
 </​code>​ </​code>​
  
-====nginx配置gzip压缩====+==== nginx配置gzip压缩====
 在http区块,添加如下参数 在http区块,添加如下参数
 <​code>​ <​code>​
行 95: 行 100:
 </​code>​ </​code>​
  
-注意:如果频道放置于CDN频道的话,注意要开启gzip_vary参数,这样源机的响应头中会包含Vary:​ Accept-Encoding头部。CDN节点会缓存编码格式不同的多份副本,根据浏览器请求的编码格式不同,响应所需编码格式的响应。+:!:注意: 
 +  * 普通列表项目如果频道放置于CDN频道的话,注意要开启gzip_vary参数,这样源机的响应头中会包含Vary:​ Accept-Encoding头部。CDN节点会缓存编码格式不同的多份副本,根据浏览器请求的编码格式不同,响应所需编码格式的响应。
  
-=====CDN频道调整=====+===== CDN频道调整=====
 如果源机的gzip vary是在已经配置CDN频道之后才增加的,那么需要跟CDN提供商确认具体的生效方法(一般需要需要对频道进行全部刷新,具体需要跟CDN提供商核实)。 如果源机的gzip vary是在已经配置CDN频道之后才增加的,那么需要跟CDN提供商确认具体的生效方法(一般需要需要对频道进行全部刷新,具体需要跟CDN提供商核实)。
  
-===== 线上案例 =====+===== 线上案例 =====
 线上存在一个以html,js,css等以文本内容为主的CDN频道。之前该CDN频道即使在源机为明确给出Vary:​Accept-Encoding的情况下,CDN节点也可以正常的区分压缩和非压缩的请求,并且给出合适的响应。之后,可能由于配置调整或者CDN系统升级导致该策略失效。在对CDN频道进行周期性遍历的时候发现CDN节点会忽略用户的Accept-Encoding请求,全部发送明文数据。\\ 线上存在一个以html,js,css等以文本内容为主的CDN频道。之前该CDN频道即使在源机为明确给出Vary:​Accept-Encoding的情况下,CDN节点也可以正常的区分压缩和非压缩的请求,并且给出合适的响应。之后,可能由于配置调整或者CDN系统升级导致该策略失效。在对CDN频道进行周期性遍历的时候发现CDN节点会忽略用户的Accept-Encoding请求,全部发送明文数据。\\
 对源机和CDN频道进行调整优化,下面是没有给出Vary头部和增加Vary头部后的带宽对比。 对源机和CDN频道进行调整优化,下面是没有给出Vary头部和增加Vary头部后的带宽对比。
行 106: 行 112:
 可以看到带宽降低了有三分之一。 可以看到带宽降低了有三分之一。
  
-注意:实际的效果与URL的内容有关,文本内容的压缩比会高一些,而一些二进制文件一般经历过压缩,再次压缩的效果不大。+:!:注意: 
 +实际的效果与URL的内容有关,文本内容的压缩比会高一些,而一些二进制文件一般经历过压缩,再次压缩的效果不大。
  
-===== 重点留意 ===== +===== 重点留意 ===== 
-CDN频道是否要开启GZIP压缩要结合实际业务考虑,如果客户端非浏览器,而是自己实现的客户端,而客户端中又没有根据Content-Encoding响应头进行解压的话,会导致乱码,业务受损。部分网页游戏也可能存在类似的情况,要结合实际业务考虑。+<color red>CDN频道是否要开启GZIP压缩要结合实际业务考虑,如果客户端非浏览器,而是自己实现的客户端,而客户端中又没有根据Content-Encoding响应头进行解压的话,会导致乱码,业务受损。部分网页游戏也可能存在类似的情况,要结合实际业务考虑。</​color>​