squid之压缩

背景介绍:

通常Web服务器都会通过gzip压缩来减少用户下载的流量,提高页面打开速度。

gzip压缩分为两种,http1.0压缩和http1.1压缩,这两种压缩的压缩方法和response header都一样,只是客户端和服务器通讯的http协议不同。

Squid2.7之前,是不支持http1.1的。在2.7版本开始,有限支持http1.1。从3.0版本开始,才完整的支持http1.1。但是因为squid3是完全重构的,很多2.7的功能并没有加到3.0当中,所以squid3并没有被大规模的应用在生产系统中,基本上都还是使用squid2.6或2.7来进行内容加速,所以需要搞定Squid支持各种Web服务器的HTTP1.0 GZIP压缩。

一、压缩分析

Squid能否正确的处理gzip,完全取决于realserver会否发送正确的Vary:头部。一般来说,反向代理环境里,自己能控制realserver。
而采用Apache这样的标准web服务器,可配置mod_deflate让它发送正确的Vary:头部。这个头部的作用,就是指示squid,应该根据客户端的请求方式不同,返回不同的压缩或非压缩目标。
浏览器请求squid上的某个目标,假设该目标在squid上有压缩过的缓存,该缓存同时包括一个"Vary:"头部(按照RFC 2616协议,对压缩过的内容Apache必须返回该头部给squid)。
Squid会根据缓存里的Vary头部的值和请求头部进行匹配,如果请求头部里包含了Accept-Encoding相应值,则squid返回压缩过的目标给浏览器。相反,如果请求头部里没有包含Accept-Encoding字段(通常是http/1.0方式),则squid会将请求转发给 realserver。按照标准,Squid不允许发送压缩过的目标拷贝给不接受Encoding的浏览器。
Squid的请求到了realserver,mod_deflate返回非压缩的内容给Squid。这个响应也包含Vary头部,但不是压缩的。 squid拿到这个响应后,更新自己的缓存(squid的缓存目标存储结构是以url为key的哈希,就是同一个url下只能存储一份cache目标),并将响应返回给客户端。
下一次如果客户的请求又包含了Accept-Encoding字段,squid会根据缓存目标的Vary头部,再去realserver取一份压缩的内容返回给客户端,并更新自己的缓存。
所以,在上述机制下,squid对gzip的兼容没有问题。但是,这里有2个明显的问题:
1. 对某个cache住的目标,一个http/1.0请求可能会导致squid强制更新其缓存。但接下来的另一个http/1.1请求又会导致squid再次更新缓存。这就极大的降低了cache命中率。
2. 某些客户端,如IE6及以下,如果发送http/1.0的请求,realserver会返回没有压缩过的内容,同时包含一个Vary:头部。这些客户端不能处理这个头部,结果就导致目标无法下载。这是IE的bug,我们做不了什么。但碰到这种情况,用户会投诉你。

这实际上取决于squid是否支持http/1.1.squid对http/1.1的兼容性代码还在开发之中.不过squid-2.7版本在这方面已做了不少工作.

如果只想配置squid作为反向代理,那么编译安装最新版的squid-2.7(该版本已包含部分http/1.1协议的补丁),在squid.conf的http_port指令后加多一个关键字http11即可,如:

http_port 80 accel vhost http11 defaultsite=www.mytest.com
这样squid就基本兼容encoding了,可以在apache上配置mod_deflate来使用gzip压缩.
不过这种情况对http/1.0的客户端可能有点问题.要完全兼容http/1.0,需要配置下apache的mod_rewrite,基于 Accept-Encoding头部进行rewrite.如果客户端声称接受encoding,那么就使用mod_deflate来压缩内容.如果客户端不接受encoding,那么rewrite规则返回302,指示客户端跳转到另一个目录.该目录不过是前述mod_deflate目录的一个符号链接, 但针对该目录没有配置mod_deflate进行压缩.这样就可解决http/1.0客户端的问题

二、具体配置

     1、squid配置

           A,将cache_vary设置成on。使squid能够缓存带有vary头的内容

            B,将broken_vary_encoding设置成all。squid.conf.default中,这个参数的示例是

                      acl apache rep_header Server ^Apache
                       broken_vary_encoding allow apache

     2、realserver对于squid压缩的支持

           要squid缓存代理完美处理压缩问题,就必须由realserver提供必要的支持

          A、realserver是nginx

           Nginx默认不支持http1.0协议通信压缩,支持http1.1,这样需要我们修改一下配置文件,具体操作步骤如下:

      1.     打开nginx.conf配置文件找到gzip on刚配置好的nginx服务此选项是被注释掉的,将其打开后,默认支持http1.1,不支持http1.0

          2.     怎样设置能使得http1.0支持gzip压缩,需要手动添加配置如下:

          gzip on; #打开gzip压缩

              gzip_http_version 1.0;    #允许http1.0协议压缩

                gzip_min_length 1000; #压缩的最小字节(可以不设置)

              gzip_buffers 4 8k;  

              gzip_types text/plain application/x-javascript text/css text/html application/xml; #压缩类型

              gzip_vary on; #开启vary

 

        设置完毕后保存,将其nginx服务重启一下,测试就可以了

        B、realserver是apache

                 Apache 默认就支持http1.0协议通信压缩,不需要特定配置,但是要制定那些文件类型压缩需要修改配置文件,具体如下:

                 apache2.2.3版本为例:

                1.      首先查找mod_deflate.c

                   将安装包解压后进入/usr/local/src/httpd-2.2.3/modules/filters目录下

                2.      然后安装mod_deflate模块

                /usr/local/apache/bin/apxs -i -c -a mod_deflate.c

                3.      配置mod_deflate

                   编辑/usr/local/apache/conf/http.conf找到LoadModule deflate_module     modules/mod_deflate.so将其模块打开

                4.      设置制定文件类型,然后保存重启服务

 

                5.      完毕后需要将相关文件进行添加vary头信息,然后重启网站,就可以实现通过代理压缩的功能.

 

 

 

 

 

 

 

三、压缩后影响

        解决 Accept-Encoding 不一致造成的多份缓存问题

解决的是 IE Firefox 搜索引擎spider 的 Accept-Encoding 不一致造成的多份缓存问题
MSIE 的 Accept-Encoding 是 gzip, deflate
Firefox Googlebot 的是 gzip,deflate (之间没有空格)
多份缓存说明穿透的风险 还是有些危险的
可以通过修改源码解决不同浏览器缓存问题
--- squid-2.6.STABLE21.orig/src/http.c 2008-04-02 09:03:47.000000000 +0800
+++ squid-2.6.STABLE21/src/http.c 2008-07-10 21:17:26.000000000 +0800
@@ -387,14 +387,20 @@
  }
  strListAdd(&vstr, name, ',');
  hdr = httpHeaderGetByName(&request->header, name);
- safe_free(name);
  value = strBuf(hdr);
  if (value) {
+     if (strcmp(name, "accept-encoding") != 0) {
      value = rfc1738_escape_part(value);
      stringAppend(&vstr, "=/"", 2);
      stringAppend(&vstr, value, strlen(value));
      stringAppend(&vstr, "/"", 1);
+     } else {
+  if(strstr(value,"gzip") != NULL || strstr(value,"deflate") != NULL) {
+       stringAppend(&vstr, "=/"gzip,/%20deflate/"", 18);
+  }
+     }
  }
+ safe_free(name);
  stringClean(&hdr);
     }
     safe_free(request->vary_hdr); 

这里不考虑 gzip deflate 的大写问题
源码修改出处:http://windtear.net/2008/07/squid_patch_accept-encoding_multi_cache.html

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值