为什么IIS7/7.5的Gzip不起作用我在如何开启IIS7或IIS7.5的HTTP压缩(GZip) 一文中介绍了IIS7对于gzip压缩的相关配置,以及默认情况下,由于IIS7将Javascript配置为动态压缩(Dynamic Compression),受CPU还有其他因素的影响,不一定会返回gzip压缩后的内容。 但是前阵子发现,尽管将Javascript配置成了静态压缩,请求Javascript脚本文件的时候偶尔还是会出现没有gzip的情况。这篇文章和大家分享一下我遇到的这个问题以及解决这个问题的过程和思路,希望对大家有所帮助。
“随机”的gzip行为
问题的症状非常简单而又奇怪。有时候连续访问脚本多次,刚开始没有gzip,再次访问又有gzip。等过好一会再去访问,gzip又没有了。有的时候则是无论怎么访问都不给我返回gzip后的响应。
问题的分析
排除了CPU负载过大的因素,因为发现当深夜机器CPU负载正常的时候也一样出现这样的问题。
在系统日志中发现以下Warning条目,引起了我的注意:
Warning 2010/4/13 6:32:41 IIS-W3SVC-WP 2264 None
The directory specified for caching compressed content C:\inetpub\temp\IIS Temporary Compressed Files\XXX is invalid. Static compression is being disabled.
通过日志筛选,发现从09年7月份就一直出现这样的Warning了,而且出现频率是隔1-3天左右。
这个文件夹是IIS用于存放压缩后的静态内容缓存。按照上面日志的意思,是说这个目录出了问题,导致静态压缩功能被禁用了。但是我明明可以访问这个文件夹,而且里头确实还放着缓存的脚本。
IIS论坛上提这个问题的帖子很多,但最终得到解答的没看到。不过其中一些人的回复倒是给了我不少思路。其中有人说道可能是文件夹权限问题,我看了看那个压缩缓存目录,上面的权限的确是应用程序池的身份,没有问题。使用ProcessMonitor监测了w3wp.exe进程的活动情况,没有看到这个进程在访问文件系统时出现错误。
后来在网上看到了Kanwaljeet Singla(IIS开发团队成员)的一篇文章,介绍IIS7相比IIS6在压缩模块上的改动,文中提到了一点,从IIS7开始,为了降低开销,IIS只对那些频繁访问的静态资源启用压缩。通过IIS7新引入的两个配置选项frequentHitThreshold和frequentHitTimePeriod,我们可以设定,当某个资源在frequentHitTimePeriod时间内被连续访问了frequentHitThreshold次,那么就算是“频繁访问”了。默认的配置是10秒钟内连续对同一Url发起2次请求就算此Url对应的资源属于频繁访问的资源,IIS服务器就会对其进行压缩,然后丢入缓存目录。
这也就解释了为什么有时候第一次请求脚本的时候,服务器没有返回gzip压缩后的内容,而是等你接着下一次访问的时候才会返回gzip响应。
但是按照这篇文章提到的IIS的设计理念,一旦资源被压缩缓存过,那么以后就不会再应用这个“频繁访问”的检测逻辑了,因为毕竟已经没有压缩开销了。而我非常确信这个脚本已经被缓存在服务器硬盘上了,那为什么我过一段时间再去访问的时候还是没有gzip呢?
在IIS7中有一个功能,叫做失败请求跟踪(Failed request tracing),允许技术人员跟踪那些出问题的请求在IIS内部都发生了什么事。为了揭开我的疑问,我对此网站开启了失败请求跟踪。
(责任编辑:ken)