对于经典应用程序池,Gzip压缩在IIS7.5中不起作用

时间:2016-04-28 17:28:58

标签: asp.net iis compression gzip

我试图弄清楚为什么使用经典应用程序池的一个站点不会被压缩。此应用程序池已启用32位。我在applicationHost.config中有以下设置。

  <httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
        <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll"  dynamicCompressionLevel="4" staticCompressionLevel="9"/>
        <scheme name="deflate" dll="%Windir%\system32\inetsrv\gzip.dll"  dynamicCompressionLevel="4" staticCompressionLevel="9"/>

        <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>
        <dynamicTypes>
          <add mimeType="text/*" enabled="true" />
          <add mimeType="message/*" enabled="true" />
          <add mimeType="application/javascript" enabled="true" />
          <add mimeType="*/*" enabled="false" />
       </dynamicTypes>
    </httpCompression>

在global.asax文件中   Sub Application_PreRequestHandlerExecute(ByVal sender As Object,ByVal e As EventArgs)

    Dim app As HttpApplication = TryCast(sender, HttpApplication)
    Dim acceptEncoding As String = app.Request.Headers("Accept-Encoding")
    Dim prevUncompressedStream As Stream = app.Response.Filter

    If app.Context.CurrentHandler Is Nothing Then
        Return
    End If

    If Not (TypeOf app.Context.CurrentHandler Is System.Web.UI.Page) OrElse app.Context.CurrentHandler.[GetType]().Name = "SyncSessionlessHandler" OrElse app.Request("HTTP_X_MICROSOFTAJAX") IsNot Nothing Then
        Return
    End If

    If acceptEncoding Is Nothing OrElse acceptEncoding.Length = 0 Then
        Return
    End If

    acceptEncoding = acceptEncoding.ToLower()

    If acceptEncoding.Contains("gzip") Then
        ' gzip
        app.Response.Filter = New GZipStream(prevUncompressedStream, CompressionMode.Compress)
        app.Response.AppendHeader("Content-Encoding", "gzip")
    ElseIf acceptEncoding.Contains("deflate") OrElse acceptEncoding = "*" Then
        ' deflate
        app.Response.Filter = New DeflateStream(prevUncompressedStream, CompressionMode.Compress)
        app.Response.AppendHeader("Content-Encoding", "deflate")
    End If
End Sub

我加倍检查我是否安装了dynamicCompression功能。在最终输出中,Content-Encoding标头一直被删除。我还应该看看什么?我读到一些函数不适用于经典应用程序池。这会导致问题吗?

1 个答案:

答案 0 :(得分:0)

IIS 7改进了内部压缩功能,使其比以前的版本更容易利用内置于Web服务器的压缩。 IIS 7还支持动态压缩,允许自动压缩在您自己的应用程序(ASP.NET或其他!)中创建的内容。该方案基于内容类型嗅探,因此适用于任何类型的Web应用程序框架。

虽然对于大多数文本内容(text/*,包括HTML和CSS,以及JavaScript,Atom,XAML,XML),IIS 7上的静态压缩非常容易设置和打开,设置动态压缩比较复杂,主要是因为各种默认压缩设置在IIS下面的多个位置设置 - &gt; ASP.NET层次结构。

让我们看一下可用的两种方法:

  • 静态压缩
    压缩硬盘中的静态内容。 IIS可以通过压缩文件一次并将压缩文件存储在磁盘上并在请求静态内容且未更改时为压缩别名提供服务来缓存此内容。这方面的开销很小,应该积极地启用。
  • 动态压缩
    适用于应用程序生成的应用程序 你的ASP.NET应用程序。与静态内容不同,动态内容必须是 每次请求它的页面重新生成它时都会压缩 内容。因此,动态压缩的影响要大得多 静态缓存。

如何配置压缩

IIS 7.x中的压缩在.config空间中配置了两个<system.WebServer>文件元素。可以在IIS / ASP.NET配置管道中的任何位置设置元素,从ApplicationHost.config一直到本地web.config文件。以下内容来自IIS 7.5上ApplicationHost.config(位于%windir%\System32\inetsrv\config文件夹)中的默认设置,并进行了一些小调整(添加了json输出并启用了动态压缩):

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <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" doDynamicCompression="true" />

  </system.webServer>
</configuration>

您可以在此处找到关于密钥的文档:

httpCompression元素 - 什么以及如何压缩

基本上httpCompression配置要压缩的类型以及如何压缩它们。它指定处理gzip编码的DLL以及要压缩的文档类型。类型是基于mime类型设置的,它们查看HTTP响应中返回的Content-Type标头。例如,我将mime类型的application / json添加到上面的动态压缩类型中,以允许压缩内容,因为我有相当多的AJAX内容被发送到客户端。

urlCompression元素 - 启用和禁用压缩

urlCompression元素是一种快速打开和关闭压缩的方法。默认情况下,服务器范围内启用静态压缩,并在服务器范围内禁用动态压缩。这可能有点令人困惑,因为httpCompression元素也有一个doDynamicCompression属性,默认情况下设置为true,但同名的urlCompression属性实际上会覆盖它。

urlCompression元素只有三个属性:doStaticCompressiondoDynamicCompressiondynamicCompressionBeforeCachedoCompression属性是否是启用压缩的最终决定因素,因此最好是explcit! doDynamicCompression='false”的默认值,但是doStaticCompression="true"默认启用静态压缩,动态压缩不

因为静态压缩在IIS 7中非常有效,所以它默认在服务器范围内启用,并且可能没有理由改变该设置。然而,动态压缩由于资源密集程度较高,因此默认情况下处于关闭状态。如果要启用动态压缩,则必须处理一些怪癖,即在ApplicationHost.config中启用它不起作用。设定:

<urlCompression doDynamicCompression="true" />

applicationhost.config中的

似乎没有任何效果,我不得不将此元素移动到我的本地web.config中以使动态压缩工作。这实际上是一个明智的选择,因为您不太可能希望在服务器上的每个应用程序中进行动态压缩。相反,动态压缩应该在有意义的地方有选择地应用。但是,无法记录applicationhost.config中的设置不起作用(或者更有可能在某处覆盖并在配置层次结构中禁用更低)。

所以:请记得在web.config中设置doDynamicCompression=”true” !!!

静态压缩的工作原理

静态压缩适用于从磁盘上的文件加载的静态内容。由于此内容是静态的并且不会经常更改 - 例如.js.css和静态HTML内容 - 因此IIS很容易压缩然后缓存压缩内容。这种方式的工作方式是IIS将文件压缩到服务器硬盘上的特殊文件夹中,然后如果已请求压缩内容并且基础文件资源未更改,则从该位置读取内容。提供已经压缩的文件的语义非常有效 - IIS仍然会检查文件更改,但只是从压缩文件夹中提供已经压缩的文件。

压缩文件夹位于:
%windir%\inetpub\temp\IIS Temporary Compressed Files\ApplicationPool\

如果您查看子文件夹,您将找到压缩文件:

CompressedFileFolder

这些文件是预先压缩的,IIS直接将它们提供给客户端,直到更改基础文件为止。

正如我之前提到的 - 默认情况下静态压缩已启用,并且没有理由关闭该功能,因为它是高效的并且只是开箱即用。您可能想要做的一个调整是将压缩级别设置为最大值。由于IIS仅很少压缩内容,因此应用最大压缩是有意义的。您可以使用scheme元素上的staticCompressionLevel设置执行此操作:

<scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" staticCompressionLevel="9" />

除此之外,默认设置可能还不错。

动态压缩 - 不是那么快!

默认情况下,动态压缩被禁用,这实际上非常合理 - 您应该非常小心地使用动态压缩,并考虑要压缩的内容。在大多数应用程序中,压缩所有生成的内容是没有意义的,因为它会产生大量的开销。 Scott Fortsyth有一篇很棒的文章,详细介绍了一些性能数字以及动态压缩的影响程度。根据服务器的繁忙程度,您可以使用压缩功能,看看它对服务器性能的影响。

还可以调整一些设置以最大限度地减少动态压缩的开销。具体来说,httpCompression键有几个与CPU相关的键,可以帮助最小化动态压缩对繁忙服务器的影响:

  • dynamicCompressionDisableCpuUsage
  • dynamicCompressionEnableCpuUsage

默认情况下,这些设置为9050,这意味着当CPU达到90%时,压缩将被禁用,直到CPU利用率下降到50%。同样,这实际上是非常明智的,因为它在可用时利用来自压缩的CPU功率,并且在达到阈值时下降。在利用率较低时,大型服务器上的一些额外CPU功率是一种很好的方式。这些设置也是你可能需要玩的东西。我可能会将上限设置为略低于90%,可能约为70%,这使得这项功能只有在有足够的电量时才能启动。我不确定IIS使用的这些CPU读数有多精确,因为即使在低负载期间,Web服务器上的CPU使用率也会急剧上升。不要相信设置 - 在实时环境中进行一些负载测试或监控服务器,以查看对您的环境有意义的值。

最后,对于动态压缩,我倾向于为JSON数据添加一个Mime类型,因为我的很多应用程序通过线路发送大块JSON数据。您可以使用application / json内容类型执行此操作:

<add mimeType="application/json" enabled="true" />

Deflate Compression怎么样?

默认压缩是GZip。该文档提示您可以使用不同的压缩方案,并提及Deflate压缩。当然,您可以将压缩设置更改为:

<scheme name="deflate" dll="%Windir%\system32\inetsrv\gzip.dll" staticCompressionLevel="9" />

获得deflate样式压缩。 deflate算法产生稍微更紧凑的输出,所以我倾向于比GZip更喜欢它,但是更多的HTTP客户端(除了浏览器)支持GZip而不是Deflate,所以如果你构建Web API,请小心这个选项。

我也有一些问题,上面的值实际上是立即应用的。在applicationhost.config中更改方案并没有立即显示在该站点上。它要求我做一个完整的IISReset,以便在我看到更改以缩小压缩内容之前显示该更改。压缩后的内容稍微压缩一点 - 不确定它是否值得稍微不那么常见的压缩类型,但至少可以使用该选项。

IIS 7终于制作了GZip Easy

总之,IIS 7最终使GZip变得简单,即使配置设置有点迟钝且文档严重缺乏。但是一旦你知道我在这里描述的基本设置以及你可以在本地web.config中覆盖所有这些的事实,就可以直接配置GZip支持并根据你的需要进行调整。

静态压缩完全没有用,因为与直接静态文件服务相比,它增加了很少的开销,并提供了可靠的压缩。动态压缩有点棘手,因为它会给服务器增加一些开销,因此可能需要进行一些调整才能在CPU负载与压缩比之间取得适当的平衡。看看像亚马逊,雅虎,NewEgg等大型网站 - 他们都使用

参考:

http://weblog.west-wind.com/posts/2011/May/05/Builtin-GZipDeflate-Compression-on-IIS-7x