asp.net - 对于传统的应用程序池,Gzip压缩在IIS7.5中不起作用

标签 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作为对象,ByVal e作为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 header 始终被删除。我还应该看什么?我读到某些功能不适用于经典应用程序池。这是引起问题的原因吗?

最佳答案

IIS 7极大地改善了内部压缩功能,使其比以前的版本更容易利用Web服务器内置的压缩​​功能。 IIS 7还支持动态压缩,该动态压缩允许自动压缩在您自己的应用程序(ASP.NET或其他!)中创建的内容。该方案基于内容类型嗅探,因此可与任何类型的Web应用程序框架一起使用。
虽然IIS 7上的静态压缩非常容易设置,并且默认情况下对于大多数文本内容(text/*,包括HTML和CSS,以及JavaScript,Atom,XAML,XML)都可以将其打开,但是设置动态压缩有点涉及更多的原因,主要是因为在IIS –> 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
  • urlCompression

  • httpCompression 元素–什么以及如何压缩
    基本上,httpCompression配置要压缩的类型以及如何压缩它们。它指定处理gzip编码的DLL以及要压缩的文档类型。根据mime-types设置类型,该mime-types会查看HTTP响应中返回的Content-Type头。例如,我在上面的动态压缩类型中添加了application/json到mime类型,以允许该内容也被压缩,因为我有很多AJAX内容被发送到客户端。
    urlCompression 元素–启用和禁用压缩urlCompression元素是打开和关闭压缩的快速方法。默认情况下,在服务器范围内启用静态压缩,而在服务器范围内禁用动态压缩。这可能有点令人困惑,因为httpCompression元素还具有doDynamicCompression属性,默认情况下将其设置为true,但是具有相同名称的urlCompression属性实际上会覆盖它。urlCompression元素仅具有三个属性:doStaticCompressiondoDynamicCompressiondynamicCompressionBeforeCachedoCompression属性是是否启用压缩的最终决定因素,因此,最好公开一下!默认为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 key 具有几个与CPU相关的 key ,可以帮助最大程度地减少动态压缩对繁忙服务器的影响:
  • 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" />压缩压缩又如何呢?
    默认压缩为GZip。该文档提示您可以使用其他压缩方案,并提到Deflate压缩。确实可以将压缩设置更改为:<scheme name="deflate" dll="%Windir%\system32\inetsrv\gzip.dll" staticCompressionLevel="9" />获得压缩风格的压缩。 deflate算法产生的输出更加紧凑,因此我倾向于使用它而不是GZip,但是与Deflate相比,更多的HTTP客户端(浏览器除外)支持GZip,因此在构建Web API时请谨慎使用此选项。
    我还有些问题,上面的值实际上马上就被应用了。更改applicationhost.config中的方案并没有立即显示在网站上。它要求我做一个完整的IISReset才能使所做的更改显示出来,然后再看到更改以缩小压缩的内容。使用deflate压缩的内容稍微多一些-不确定是否值得使用稍微不那么常用的压缩类型,但是至少可以使用该选项。
    IIS 7最终使GZip变得简单
    总而言之,即使配置设置有些晦涩,并且严重缺乏文档说明,IIS 7最终还是使GZip变得容易。但是,一旦您了解了我在这里描述的基本设置以及可以在本地web.config中覆盖所有这些设置这一事实,就可以直接配置GZip支持并根据您的需要进行微调。
    静态压缩完全没有麻烦,因为与直接静态文件服务相比,它增加了很少的开销,并且提供了可靠的压缩。动态压缩有点棘手,因为它确实会增加服务器的开销,因此可能需要进行一些调整才能使CPU负载与压缩率达到正确的平衡。查看大型网站,例如Amazon,Yahoo,NewEgg等-他们都使用

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

    关于asp.net - 对于传统的应用程序池,Gzip压缩在IIS7.5中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36921618/

    相关文章:

    c# - 复制的 NameValueCollection 的 ToString() 未输出所需的结果

    powershell - 使用 Get-IISAppPool 并在同一 session 中创建新应用程序池时出现奇怪问题

    algorithm - 具有跨文件压缩表的文件系统

    mysql - 如何使用Asp.net从MySql数据库获取salt?

    asp.net - 向 System.Web.UI.Control 添加样式

    powershell - 启用 IIS 可选功能 IIS-ASPNET 和 IIS-ManagementConsole 时出错

    iphone - 如何解压缩 AES-256 加密的 Zip 文件?

    linux - 为什么同一文件的两个 tarball 的 md5 散列不同?

    c# - 在 C# 页面处理期间, session 可以过期吗

    c# - IIS 花费大量时间来交付第一个 javascript 和图像文件