用代码进行IIS压缩的GZipping?

7
我正在将gzip应用于所有静态内容和我的.NET 4站点的HTML输出。
我还启用了IIS 7.5中的压缩(静态和动态),但我发现启用IIS中的压缩会覆盖这些资源的Vary:Accept-Encoding头信息。
因此,我想知道是否真的需要在IIS中启用压缩,因为我已经在使用gzip进行压缩?
所以,我进行了一些测试,以下是我的发现:
Utilizing IIS Static and Dynamic Compression, with code compression:
CPU Load: 35%
Memory Load: 28M

Utilizing IIS Static and Dynamic Compression, without code compression:
CPU Load: 34%
Memory Load: 28M

Non-Utilizing Static and Dynamic Compression In IIS, with code compression:
CPU Load: 14%
Memory Load: 32M

根据我的调查结果,我同意,在代码中进行压缩时,没有必要使用IIS压缩。即使内存消耗略高,CPU负载也显著较低,因此在提供文件方面,采用代码中的压缩方法更加高效。

实际上,我的目的是找出并消除IIS覆盖Vary: Accept-Encoding头的问题。无论是否启用IIS压缩,这似乎都没有影响。该头仍未被添加...那么,你能帮忙解决吗?

这是我正在实施的缓存代码,请注意,在触发包含此代码的方法之前,我会通过context.Response.ClearHeaders()清除标头:

    With context.Response
        .AddHeader("Cache-Control", "store, cache")
        .AddHeader("Pragma", "cache")
        .AddHeader("Cache-Control", "max-age=21600")
        .AddHeader("ETag", Date.Now.Ticks)
        .AddHeader("Expires", DateTime.Now.AddYears(1).ToString("ddd, dd MMM yyyy hh:mm:ss") + " GMT")
        .AddHeader("Vary", "Accept-Encoding")
        .AppendHeader("Vary", "Accept-Encoding")
        .Cache.SetVaryByCustom("Accept-Encoding")
        .Cache.SetOmitVaryStar(True)
        .Cache.VaryByParams.IgnoreParams = True
        .Cache.SetAllowResponseInBrowserHistory(True)
        .Cache.SetCacheability(Web.HttpCacheability.Public)
        .Cache.SetValidUntilExpires(True)
        .Cache.SetLastModified(DateTime.Now.AddYears(-1).ToString("ddd, dd MMM yyyy hh:mm:ss") + " GMT")
        .CacheControl = "public" '
        .Expires = 24 * 60 * 366
        .ExpiresAbsolute = DateTime.Now.AddYears(1).ToString("ddd, dd MMM yyyy hh:mm:ss") + " GMT"
    End With

我在想相反的情况:当IIS提供压缩功能时,是否真的需要在代码中进行压缩?弄清楚你这样做的真正原因是否有充分的理由。 - Kevin P. Rice
你为什么要添加自己的编码方式?它是什么样的编码方式? - Akash Kava
我想确保静态资源被压缩。大多数共享托管系统默认情况下不启用压缩。因此,通过在代码中进行操作,可以确保在这些系统上资源将被gzip压缩。只有“文本”文件会被压缩...css、js、html、字体文件等。 - Kevin
@o7thWebDesign,不深入了解您的问题,我有两个建议:(1)我怀疑您的测试准确性有一个特定的原因:听起来像是您正在动态地提供静态内容。这将排除所有静态压缩和缓存。如果没有通过ASP.NET管道提供静态内容,则会获得最佳可扩展性。(2)关于Vary头,我对所有缓存控制头的详细理解还不够,无法说明何为正确设置。请查看所有配置文件设置(http://msdn.microsoft.com/en-us/library/aa347461%28v=vs.90%29.aspx)。 - Kevin P. Rice
实际上,它是动态提供的。所有脚本、样式表、图像和字体都通过 httphandler 传递以设置正确的缓存标头。这只是必要的,因为并非所有第三方主机都通过 IIS 进行此操作。 - Kevin
在IIS Gzip模块中覆盖“Vary”标头是一个已知的错误。请在此处投票:http://connect.microsoft.com/VisualStudio/feedback/details/758474/iis-gzip-compression-filter-removes-pre-existing-vary-header - Dmitry
1个回答

5
你需要明确知道你在代码中应用压缩的MIME类型。然后,你可以禁用那些MIME类型的IIS压缩。
你的.config文件应该大致如下所示。你会注意到应用压缩的MIME类型都列出来了。明智地关闭代码或IIS中的MIME类型压缩,以使在代码中压缩的内容不会被IIS压缩,反之亦然。
例如,如果你的HTML全部在代码中压缩,你可以指定:
    <add mimeType="text/html" enabled="false" />

applicationHosts.config文件摘录:

<system.webServer>
<httpCompression
    directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files"
    dynamicCompressionDisableCpuUsage="90"
    dynamicCompressionEnableCpuUsage="80"
    maxDiskSpaceUsage="100" minFileSizeForComp="2700"
    noCompressionForRange="true"
    sendCacheHeaders="false"
    staticCompressionDisableCpuUsage="100"
    staticCompressionEnableCpuUsage="80"
    >
    <scheme name="gzip"
        dll="%Windir%\system32\inetsrv\gzip.dll"
        dynamicCompressionLevel=”4”
        staticCompressionLevel=”7” />
    <dynamicTypes>
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <add mimeType="application/javascript" enabled="true" />
        <add mimeType="application/json" enabled="true" />
        <add mimeType="application/xml" enabled="true" />
        <add mimeType="*/*" enabled="false" />
    </dynamicTypes>
    <staticTypes>
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <add mimeType="application/javascript" enabled="true" />
        <add mimeType="application/json" enabled="true" />
        <add mimeType="application/atom+xml" enabled="true" />
        <add mimeType="application/rss+xml" enabled="true" />
        <add mimeType="application/xaml+xml" enabled="true" />
        <add mimeType="application/xml" enabled="true" />
        <add mimeType="image/svg+xml" enabled="true" />
        <add mimeType="*/*" enabled="false" />
    </staticTypes>
</httpCompression>
<urlCompression doDynamicCompression="true"
    dynamicCompressionBeforeCache=”true” />
</system.webServer>

请注意,如果修改applicationHosts.config,它将影响服务器上所有的网站,因此您需要知道任何不在代码中应用压缩的网站将完全不会被压缩。
另外,请注意,二进制内容一般不应该被压缩(例如图片、视频),这些资源已经在各自的容器中进行了压缩(例如.jpg、.mp4)。请确保不要压缩已经被压缩的内容类型。
有关压缩设置的更多详细信息,请查看我的回答:https://dev59.com/g0XRa4cB1Zd3GeqPuMD7#10051876

确实很方便,但我的做法是确保如果某个使用该系统的人将其安装在不允许此类高级访问的服务器上,也可以进行压缩。 - Kevin
所以在我的测试服务器(位于地下室),我已经设置了IIS 7.5来压缩所有静态和动态资源。我还将我的代码设置为gzip任何js、css、html输出、字体文件等...因为我需要考虑那些可能在没有启用IIS压缩的服务器上使用我的系统的人。我的担忧是,在启用压缩的服务器上,它会浪费服务器资源吗?这真的有必要吗? - Kevin
1
@o7thWebDesign 我非常确定如果在两个地方启用压缩,将会浪费资源。我不知道 IIS 是否能检测到内容已经被压缩。IIS 可能会二次加密,导致破坏或更大的文件尺寸。你需要进行测试。其次,我不确定是否可以在本地 web.config 中控制 IIS 压缩;即使可以,有些管理员可能会锁定它。有两种思路:(1)追求自己的压缩复杂性以提供作为功能;或者(2)将压缩留给用户寻找更好的主机作为原因。 - Kevin P. Rice
只有在关心节省带宽和提高页面加载速度时才需要压缩。 - Kevin P. Rice
抱歉,之前没有将这个回复作为答案发布(只是不想自己接受答案)=)已经编辑了初始问题。顺便说一下,我正在构建这个东西来为我的网站渲染引擎构建一个CDN。 - Kevin
显示剩余2条评论

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