簡體   English   中英

對於經典應用程序池,Gzip壓縮在IIS7.5中不起作用

[英]Gzip compression doesn't work in IIS7.5 for classic application pool

我試圖弄清楚為什么使用經典應用程序池的一個站點不會被壓縮。 此應用程序池已啟用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標頭一直被刪除。 我還應該看看什么? 我讀到一些函數不適用於經典應用程序池。 這會導致問題嗎?

IIS 7顯着改進了內部壓縮功能,使其比以前的版本更容易利用內置於Web服務器的壓縮。 IIS 7還支持動態壓縮,允許自動壓縮在您自己的應用程序(ASP.NET或其他!)中創建的內容。 該方案基於內容類型嗅探,因此它適用於任何類型的Web應用程序框架。

雖然對於大多數文本內容( text/* ,包括HTML和CSS,以及JavaScript,Atom,XAML,XML),IIS 7上的靜態壓縮非常容易設置和打開,但設置動態壓縮是更多涉及,主要是因為各種默認壓縮設置在IIS - > ASP.NET層次結構中的多個位置設置。

我們來看看兩種方法中的每種方法:

  • 靜態壓縮
    壓縮硬盤中的靜態內容。 IIS可以通過壓縮文件一次並將壓縮文件存儲在磁盤上並在請求靜態內容且未更改時為壓縮別名提供服務來緩存此內容。 這方面的開銷很小,應該積極地啟用。
  • 動態壓縮
    適用於ASP.NET應用程序等應用程序的應用程序生成輸出。 與靜態內容不同,每當請求它的頁面重新生成其內容時,都必須壓縮動態內容。 因此,動態壓縮比靜態緩存具有更大的影響。

如何配置壓縮

IIS 7.x中的壓縮在<system.WebServer>空間中配置了兩個.config文件元素。 可以在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元素只有三個屬性: doStaticCompressiondoDynamicCompressiondynamicCompressionBeforeCache doCompression屬性是否是啟用壓縮的最終決定因素,因此最好是explcit! doDynamicCompression='false”的默認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" />

減壓壓縮怎么樣?

默認壓縮是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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM