IIS 7.5上的GZip压缩无法正常工作

62

我正在尝试为IIS下的静态文件支持GZip压缩(默认情况下应该是已启用的),但目前还没有生效。这里是Web应用程序的web.config文件中<system.webServer>节点下的部分内容:

<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
  <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" staticCompressionLevel="9" />
  <dynamicTypes>
    <add mimeType="text/*" enabled="true" />
    <add mimeType="message/*" enabled="true" />
    <add mimeType="application/x-javascript" enabled="true" />
    <add mimeType="application/json" enabled="true" />
    <add mimeType="*/*" enabled="false" />
  </dynamicTypes>
  <staticTypes>
    <add mimeType="text/*" enabled="true" />
    <add mimeType="message/*" enabled="true" />
    <add mimeType="application/x-javascript" enabled="true" />
    <add mimeType="application/atom+xml" enabled="true" />
    <add mimeType="application/xaml+xml" enabled="true" />
    <add mimeType="*/*" enabled="false" />
  </staticTypes>
</httpCompression>

<urlCompression doStaticCompression="true" />

我试过使用Google Chrome,在此提供请求头信息;

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8

Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3

Accept-Encoding:gzip,deflate,sdch

Accept-Language:en-US,en;q=0.8

Cache-Control:no-cache

Connection:keep-alive

Host:my-website-url

Pragma:no-cache

User-Agent:Mozilla/5.0 (Windows NT 6.0) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30

以下是响应头信息;

Accept-Ranges:bytes

Content-Length:232651

Content-Type:application/x-javascript

Date:Thu, 04 Aug 2011 08:58:19 GMT

ETag:"a69135734a50cc1:0"

Last-Modified:Mon, 01 Aug 2011 12:56:37 GMT

Server:Microsoft-IIS/7.5

X-Powered-By:ASP.NET

我检查了applicationHost.config文件,并发现一些类似以下的节点;

----

<section name="httpCompression" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />

----

<section name="urlCompression" overrideModeDefault="Allow" />

----

<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
    <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />
    <staticTypes>
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <add mimeType="application/x-javascript" enabled="true" />
        <add mimeType="application/atom+xml" enabled="true" />
        <add mimeType="application/xaml+xml" enabled="true" />
        <add mimeType="*/*" enabled="false" />
    </staticTypes>
</httpCompression>

----

<urlCompression />

我这里缺少什么?


我应该在http://serverfault.com上提出这个问题吗? - tugberk
1
我遇到了同样的问题。无论我做什么,Wireshark都显示无法压缩任何内容。 - Brain2000
你是否已经通过@Brain2000的答案得到了最终解决方案? - PreguntonCojoneroCabrón
7个回答

48

经过大量搜索,我终于找到了如何在我的IIS 7.5上启用压缩的方法。

首先,除非文件被频繁加载,否则IIS不会对其进行压缩。那就引出了一个问题,“IIS认为什么是频繁加载?” 好吧,默认情况下是10秒内2次。哎呀!

这个设置可以在web.config中更改,但需要先在applicationHost.config中解锁该部分。以下是命令:

首先解锁该部分:

C:\Windows\System32\inetsrv\appcmd.exe unlock config /section:system.webServer/serverRuntime

已解锁位于“MACHINE/WEBROOT/APPHOST”配置路径下的“system.webServer/serverRuntime”部分。

现在已经完成了,编辑web.config文件并添加serverRuntime元素:

<?xml version="1.0" encoding="UTF-8"?>
  <configuration>
    <system.webServer>
      <serverRuntime frequentHitThreshold="1" frequentHitTimePeriod="10:00:00" />
...

在这种情况下,我设置它在10小时的时间段内访问文件一次。您可以根据需要调整值。这里是解释serverRuntime元素的文档:

http://www.iis.net/configreference/system.webserver/serverruntime

希望这能帮助您使压缩正常工作。

注意:您也可以在applicationHost.config文件中设置serverRuntime元素,但我选择在web.config中更改它,因为我们有许多具有各种站点的服务器和农场,我更容易从这个粒度级别控制它。


9
原来您可以通过此参数 staticCompressionIgnoreHitFrequency 在 httpCompression 下完全避免“频繁请求”的问题。将其设置为 True 即可。 - ianbeks
1
上面的链接说明:staticCompressionIgnoreHitFrequency属性是在IIS 8.5中添加的。 - Darren
如果您决定通过Notepad ++或任何其他32位编辑器编辑x64位Windows上的%windir%\System32\inetsrv\config\applicationHost.config,您可能需要使用另一个路径,请参见:http://forums.iis.net/t/1151982.aspx - Alec
“set it to hit the file once in a 10 hour”是什么意思?如果文件在10小时内没有被请求,会发生什么?IIS会在此之后清除缓存文件吗?如果是这样,我该如何配置IIS以永远不清除我的静态内容的缓存? - Rudey
如果您在站点上包含serverRuntime元素并将其托管在尚未解锁该元素的IIS 10 / Win Server 2016上,则该站点将500,没有错误详细信息,没有日志记录,也没有其他线索说明您的站点为什么/如何失败。 - Chris Moschini
显示剩余2条评论

29

需要记住的一件事是,通常会立即返回第一个命中结果但未压缩,但它会启动一个线程在后台压缩文件,以便为将来的请求提供已压缩的响应。

此外,您尝试使用不同的客户端(例如IE)了吗?


2
哇,从您这里得到答案真是太好了,先生 :) 是的,尝试了不同的方法,但完全没有机会。也尝试了Fiddler :) 想着可能是“%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files”文件夹的权限问题,但也无法解决。我需要为我的Web应用程序的所有用户设置权限吗?因为我有近20个应用程序在运行,每个应用程序都有自己的用户帐户在服务器上。 “IIS Temporary Compressed Files”文件夹具有IIS_IUSRS用户的完全控制权限。我真的很想知道还缺少什么。 - tugberk
我该如何获取此操作的“失败请求跟踪”以查看实际错误? - tugberk
6
在技术上,压缩只适用于“频繁请求”的内容,该内容在system.webServer/serverRuntime元素下定义,并具有[frequentHitThreshold和frequentHitTimePeriod]属性。详情请见这里:http://www.ksingla.net/2006/06/changes_to_compression_in_iis7/。 - Sumo
1
我也遇到了同样的问题,所以我同时在Firefox、Chrome和IE浏览器中打开了多个窗口。在多次访问同一页面后,内容返回时是编码的。之前,我每次都使用Shift + F5刷新页面,这会获取未压缩的内容(即你提到的第一个未压缩版本)。在看到你的评论之前,我真的很困惑,所以谢谢你。微软应该更清楚地解释这种行为。 - Daniel Cotter
该死!!我疯了一样地试图找到问题,读了你的帖子后,我清除了缓存,重新加载了两次,然后它就出现了!有没有办法自动触发这个?谢谢。 - vtortola
2
原来你可以通过这个参数避免“经常请求”的问题:httpCompression下的staticCompressionIgnoreHitFrequency。将其设置为True即可。 - ianbeks

13

请确保在服务器上安装了动态压缩。在IIS下添加/删除功能。


1
我简直不敢相信,为什么你可以选择静态压缩,如果它需要启用动态压缩?但这就是解决方法。 - rob

6
花了我一段时间才明白这个问题。在applicationHost.config文件中,在system.webServer / serverRuntime节点上将frequentHitThreshold属性设置为1就可以解决问题,如http://www.iis.net/ConfigReference/system.webServer/serverRuntime所述。
您可以通过以管理员身份执行以下命令来执行此操作:
%windir%\system32\inetsrv\appcmd set config /section:serverRuntime /frequentHitThreshold:1 /commit:apphost

警告: "频繁命中" 的概念似乎不仅适用于压缩。我不知道设置这个的结果是否会产生其他后果!


这给了我“未知属性”frequentHitThreshold“”。 - Saintali
3
我认为你需要的设置是 <httpCompression staticCompressionIgnoreHitFrequency="true" /> - Rick Strahl

1
我们发现一个问题,就是我们的Azure网站因为高资源WebJob的运行而达到了最大CPU使用率。我们尝试了以上所有设置,但都没有起作用。然后我们检查了资源CPU使用情况,发现它超过了80%。在80%的CPU负载下,gzip停止工作!

1

我认为你想说的是httpCompression不能在Web.config中定义。但是,在applicationHost.config文件的system.webServer下是可以定义的。 - Sumo
每个站点在applicationHost.config文件中都有一个位置节点。我需要从那里进行配置吗?另外,我需要说明的是,在开发阶段使用iis express时压缩功能正常工作。 - tugberk
我并不是在尝试动态压缩。实际上,我也没有安装它。只有静态压缩被启用了。说实话,本应该启用的,但现在还没有。 - tugberk
好的。您可以尝试跟踪您的故障zip请求。请查看此链接:http://forums.iis.net/t/1162238.aspx#1922938。 另外,请首先检查“temp”文件夹的访问权限。请参阅此链接:http://forums.iis.net/t/1172925.aspx。 - Nastya Kholodova

0

我认为将此作为响应添加是值得的,因为它仅在注释中提到,但这是真正的解决方案,如果您想始终提供压缩资源。如果您真的不关心有人下载大文件,则调整staticCompressionIgnoreHitFrequency是可行的解决方案。

上述设置将始终进行压缩,只要CPU利用率没有触发staticCompressionDisableCpuUsage

要确保资源已压缩为100%,您应该使用:

  staticCompressionIgnoreHitFrequency true 
  staticCompressionDisableCpuUsage 100
  staticCompressionEnableCpuUsage 100

例如,如果您希望使用 web.config 进行更改,您可以使用以下代码:
<configuration>
  <system.webServer>
      <urlCompression doStaticCompression="true" doDynamicCompression="false" />
      <httpCompression staticCompressionIgnoreHitFrequency="true" staticCompressionDisableCpuUsage="100" staticCompressionEnableCpuUsage="100"/>
  </system.webServer>
</configuration>

这样做即使在 CPU 达到 100% 利用率时,第一个请求也将被压缩。

请记住,IIS 根据配置自动回收应用程序池,因此即使您设置了 10 小时,但您的应用程序池每小时重置一次,这将导致重置后的第一个调用未被压缩。

请确保知道自己在做什么,因为 GZip 仍然是一项昂贵的操作,根据您拥有的流量类型,您可能会通过调整这些设置而导致性能问题。

更多信息:https://learn.microsoft.com/en-us/IIS/wmi-provider/httpcompressionsection-class?redirectedfrom=MSDN

此外,如果感兴趣,请考虑使用 Brotli 替代 Gzip,它提供了更高级别的压缩,并对 CPU 性能影响较小。 https://learn.microsoft.com/en-us/iis/extensions/iis-compression/iis-compression-overview


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接