排查 IIS 6 或 IIS 7.x 中的 IIS 压缩问题

适用于: Internet Information Services 6.0、Internet Information Services 7.0 及更高版本

概述

为 IIS 6 或 7 Web 应用程序启用 HTTP 压缩是提高站点性能的一种方式。

管理员 GUI 不公开完全管理 IIS 所需的许多压缩属性。 它只是提供打开或关闭开关。 因此,若要完全启用 HTTP 压缩,必须使用 IIS 管理器以外的工具来更新 metabase.xml 文件。 最常用的工具是 adsutil.vbs,包含在 IIS 安装目录中。

本文可帮助你配置压缩并识别 IIS 压缩在 IIS 6 和 IIS 7.x 中可能不起作用的常见原因。

此疑难解答中使用的工具

  • Fiddler
  • 进程监视器
  • 元数据库 ACL
  • IIS 7 FREB 跟踪

验证

确定压缩是否正常工作

确定 IIS 服务器是否发送压缩响应的唯一方法是分析客户端请求和服务器响应的网络跟踪。 来自客户端的请求必须包含以下 HTTP 请求标头:

HTTP: Accept-Encoding =gzip, deflate

这让服务器知道客户端愿意接收压缩的响应并支持压缩。 返回时,来自服务器的压缩响应将包含以下 HTTP 响应标头和值:

HTTP: Content-Encoding = gzip

以下屏幕截图显示了压缩不起作用时 Fiddler 工具的输出:

“转换器”选项卡中 HTTP 压缩设置为“无压缩”的屏幕截图。

“转换器”选项卡中禁用的 HTTP 压缩部分的屏幕截图。

排查压缩问题

执行以下步骤来排查压缩问题:

  1. 在 IIS 6 或 IIS 7 中启用压缩。

    在 IIS 管理器中,右键单击 “网站 ”节点,选择“ 属性”,然后选择“ 服务”。

    HTTP 压缩的屏幕截图,其中选择了“压缩静态文件”,并将“最大临时目录大小”设置为“无限制”。

    已启用的压缩选项的屏幕截图,其中包含默认值。

  2. 指定压缩文件夹和权限。

    IIS 将压缩文件存储在可以配置的文件夹中。 默认情况下,它 %windir%\IIS Temporary Compressed Files 适用于 IIS 6 和 %SystemDrive%\inetpub\temp\IIS Temporary Compressed Files IIS 7。

    IIS_WPG(对于 IIS 7 为 IIS_IURS)必须对此文件夹具有完全控制权限。 使用 进程监视器 排查此类权限问题。

  3. 检查是否在Metabase.xml启用了压缩。

    在右侧节点的元数据库中未打开压缩。 压缩配置有三个元数据库节点:

    • w3svc/filters/compression/parameters
    • w3svc/filters/compression/gzip
    • w3svc/filters/compression/deflate

    配置 /parameters 节点是必需的。 然后,可以配置或/gzip/deflate同时配置节点或两者。 这意味着仅配置 gzip、deflate 或参数节点将不起作用。 如果配置 /parameters/gzip 节点,将启用 Gzip 压缩方案。 如果配置 /parameters/deflate 节点,将启用 Deflate 压缩方案。 最后,如果配置所有三个节点,将启用 GZip 压缩和 Deflate 压缩。

  4. 检查 IIS 6 的元数据库权限。

    默认情况下, IIS_WPG 具有读取、不安全读取、枚举密钥和写入 /LM/W3SVC/Filters权限。

    如果由于意外更改或安全强化而删除了权限,IIS 将无法初始化压缩。

    使用 metaacl.vbs 验证和修改 IIS 6 元数据库 ACL。 有关详细信息,请参阅 默认元数据库 ACL

    如果应用程序池标识(或 IIS_WPG 一般情况下的组)对元数据库密钥 W3SVC 或筛选器没有读取和写入访问权限,则会在适用于 Windows 的企业跟踪(ETW)跟踪中记录失败情况 COMPRESSION_DISABLED

    ETW 跟踪

    IISCompression: STATIC_COMPRESSION_NOT_SUCCESS - IIS has been unsuccessful doing static compression
    Reason: COMPRESSION_DISABLED
    
  5. 检查是否在Metabase.xml关闭动态或静态压缩。

    在三个配置节点(/parameters/gzip/deflate)中,可以选择启用静态和/或动态压缩。 若要为文件类型(如.txt和.html)启用静态压缩,必须将密钥设置为 HcDoStaticCompression 1 (或 TRUE)。 若要为文件类型(如 .asp、.aspx、.asmx 或 .exe)启用动态压缩,必须将密钥设置为 HcDoDynamicCompression 1 (或 TRUE)。

    例如,若要在 /parameters 节点上设置动态压缩,请使用 adsutil.vbs 运行以下命令:

    cscript.exe adsutil.vbs SET w3svc/filters/compression/parameters/HcDoDynamicCompression TRUE
    

    上一命令的输出如下所示:

    HcDoDynamicCompression          : (BOOLEAN) True
    

    在 IIS7 中

    <system.webServer>
    <urlCompression doStaticCompression="true" doDynamicCompression="true" />
    </system.webServer>
    
  6. 检查要压缩的文件类型是否在节点的/gzip/deflate相应“文件扩展名”部分中列出。

    使用 HcDoDynamicCompression 和/或 HcDoStaticCompression 键启用压缩后,请指定必须实际压缩哪些文件类型。 默认情况下,STATIC 压缩使用文件类型,例如.htm、.html和.txt,动态压缩使用.asp、.dll和.exe。 如果要压缩不同的文件类型(例如.aspx),请根据所使用的压缩类型,将其添加到和或/deflate节点中的/gzip相应文件扩展名部分。 对于静态文件压缩(如 .html、txt 和 xml),请将文件扩展名添加到 HcFileExtensions 属性。 对于动态压缩(如.asp、.aspx和 .asmx),请将其添加到 HcScriptFileExtension 属性。

    对于静态文件

    adsutil.vbs SET w3svc/filters/compression/gzip/HcFileExtensions "htm" "html" "txt"
    
    adsutil.vbs GET w3svc/filters/compression/gzip/HcFileExtensions
    

    上一个命令显示以下输出:

    HcFileExtensions : (LIST)  (3 Items)
    "htm"
    "html"
    "txt"
    

    对于动态文件

    adsutil.vbs SET w3svc/filters/compression/gzip/HcScriptFileExtensions "asp" "dll" "exe" "aspx"
    adsutil.vbs get w3svc/filters/compression/gzip/HcScriptFileExtensions
    

    上一个命令显示以下输出:

    HcFileExtensions : (LIST)  (4 Items)
    "asp"
    "dll"
    "exe"
    "aspx"
    

    在 IIS7 中

    <httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files" minFileSizeForComp="1000">
    <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>
    <dynamicTypes>
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <add mimeType="application/x-javascript" enabled="true" />
        <add mimeType="*/*" enabled="false" />
    </dynamicTypes>
    </httpCompression>
    <system.web.extensions>
    <scripting>
        <scriptResourceHandler enableCompression="false" />
    </scripting>
    </system.web.extensions>
    

    注意

    必须使用正确的语法配置 HcFileExtensionsHcScriptFileExtensions 属性。 任何尾随空格或不必要的引号或回车将导致属性配置错误。 遗憾的是, 如果添加额外的空间,adsutil.vbs 不会显示错误,因此需要非常小心。 此外,不能将值复制或粘贴到命令提示符或 metabase.xml 文件(元数据库直接编辑)中,并且必须手动键入它。

  7. 检查是否在主级别设置压缩,但正在由子级别的设置重写。

    将在级别启用 w3svc/filters/compression 压缩。 但是,可能是通过网站或应用程序级别的设置来替代它。

    例如,如果已HcDoDynamicCompression设置为w3svc/filters/compressionTRUE级别,并且对于默认网站已DoDynamicCompression设置为FALSE,则不会发生对默认网站的请求的响应的动态压缩。

  8. 检查防病毒程序是否已扫描保存压缩文件的目录。

    在运行 IIS 的服务器上启用压缩并从 IIS 压缩目录中提供 HTTP 请求时,可能会返回 0 字节文件,而不是预期的文件。

    注意

    仅当启用 HTTP 静态压缩时,才会出现这些症状。

    发生这种情况是因为 IIS 服务器上运行的防病毒软件正在扫描 IIS 压缩目录。

    因此,需要从防病毒软件的扫描列表中排除 IIS 压缩目录。

  9. 检查所请求的 URL 是否包含斜杠,作为传递给执行 DLL 文件的参数的一部分。

  10. 检查 ISAPI 筛选器是否修改请求或响应标头。

    ISAPI 正在执行发送操作,并且不会将完整的 HTTP 标头集与实体一起发送到 HTTP_COMPRESSION::DoDynamicCompression。 由于 DoDynamicCompression 不会从 ISAPI 接收所有数据,因此无法压缩响应。 第三方和/或非Microsoft ISAPIs 通过将标头放入用于实体正文的函数中或用于 HTTP 标头的函数中的实体正文,或者未提供任何标头来执行此操作。 发生这种情况时,ISAPI 筛选器 SF_NOTIFY_SEND_RESPONSE、AddResponseHeaders 或动态压缩等操作都将失败。 ISAPI 需要将标头和实体分别放置在正确的位置。

  11. 检查响应状态代码是否为 200 以外的代码。 在 IIS 6 或 7 中,只有具有 HTTP 200 状态的响应才会压缩。

    不会压缩包含 200 以外的状态代码的响应。 必须编写一个 HTTPModule 实现相同的操作。

  12. 检查请求是否包含一个 Via: header,指示 Via headers 请求是通过代理传入 IIS 的。

    许多代理无法正确处理压缩标头,并且不应向客户端提供压缩数据。 因此,默认情况下,当请求具有 Via 标头时,不允许压缩响应。 可以通过将 HcNoCompressionForProxies 元数据库密钥设置为 True..

  13. 检查请求是否为静态页面,响应是否包含文档页脚。 文档页脚将导致静态压缩失败。

  14. 检查静态压缩是否正常工作。 如果在 IIS 中的根级别安装了通配符应用程序映射,则可能发生这种情况。 例如,我们在服务器上具有.html或.txt扩展的应用程序映射,这会使 IIS 将 .txt请求视为动态请求而不是静态请求,并且由于.txt不是动态压缩列表中的扩展,因此它不会被压缩。

  15. 检查 IIS 压缩和 Accept-Encoding: identity 字段是否存在。

    根据RFC2616,如果 Accept-Encoding 请求中存在字段,并且服务器无法发送响应(根据 Accept-Encoding 标头可接受),则服务器应使用 406(不可接受)状态代码发送错误响应。 如果请求中不存在 Accept-Encoding 任何字段,服务器可能会假定客户端将接受任何内容编码。 在这种情况下,如果“identity”是可用的内容代码之一,则服务器应使用“标识”内容代码,除非它具有其他信息,即不同的内容代码对客户端有意义。

  16. 检查是否使用 ETW 跟踪来排查 IIS 压缩问题。

    Windows 事件跟踪(ETW)是 Windows OS 的一项功能,可用于排查 HTTP 请求的问题。

    下面是排查 IIS 压缩问题的步骤。

    1. 创建名为 IISProviders.txt 的文本文件,并将关注内容放入文件中。IIS:WWW Server“是提供程序名称,0xFFFFFFFE表示所有事件的跟踪,5 表示详细级别。

    2. 打开命令提示符,并运行以下命令。

      logman start trace compressionTrace -pf IISProviders.txt -ets
      
    3. 再现此问题。

    4. 运行以下命令以停止跟踪。

       logman stop trace compressionTrace -ets
      
    5. 将跟踪转换为文本文件。

      跟踪报表将二进制跟踪数据转换为文本,并在执行 tracerpt 命令的目录中生成两个文件:

      tracerpt compressionTrace.etl
      
      • Summary.txt 包含有关跟踪会话的一般详细信息,包括使用了哪些提供程序

      • DumpFile.csv 包含文本格式的实际跟踪数据

    6. 读取跟踪文件以查找有用的信息。 打开 dumpfile.csv,找到COMPRESSION_NOT_SUCCESS等关键字。 下面是一个示例:

      IISCompression, STATIC_COMPRESSION_NOT_SUCCESS, 0x000008B0, 129744354075770195, 0, 0, {00000000-0000-0000-0700-0060000000bd}, "NO_MATCHING_SCHEME", 0, 0
      

    此错误NO_MATCHING_SCHEME意味着此扩展或 Accept-Encoding 没有压缩方案匹配。 有关压缩错误的详细列表,请参阅 压缩错误列表。

  17. 检查是否使用了 FREB 跟踪来排查 IIS 压缩问题。

    有关详细步骤,请参阅 在 IIS 7 中使用跟踪排查失败的请求。

    下面是使用 IIS 7 FREB 跟踪排查压缩问题的示例。

    使用错误消息跟踪压缩问题的屏幕截图。

压缩错误列表

有关压缩错误的详细列表,请参阅下表。

注意

以下原因适用于 IIS 6 和 IIS 7。

Reason 说明
NO_ACCEPT_ENCODING 客户端不发送接受编码。
COMPRESSION_DISABLED 压缩被禁用,因为找不到合适的配置。
NO_COMPRESSION_10 服务器未配置为压缩 1.0 请求。
NO_COMPRESSION_PROXY 服务器未配置为压缩代理请求。
NO_MATCHING_SCHEME 此扩展/Accept-Encoding 没有压缩方案匹配。
UNKNOWN_ERROR 未知错误。
NO_COMPRESSION_RANGE 服务器未配置为压缩范围请求
FILE_TOO_SMALL 小于压缩阈值的文件。
FILE_ENCRYPTED 文件已加密。
COMPRESS_FILE_NOT_FOUND 压缩副本不存在。
COMPRESS_FILE_STALE 压缩副本已过期。
NO_MATCHING_CONTENT_TYPE 服务器未配置为压缩此扩展的内容类型。
HEADERS_SENT_TWICE 为同一响应发送两次标头。
NO_HEADER_SENT 实体正文发送之前未发送标头。
NOT_SUCCESS_STATUS 响应状态代码未成功(200)。
ALREADY_CONTENT_ENCODING 响应中已存在内容编码。

注意

以下原因仅适用于 IIS 7。

Reason 说明
FOOTER_ENABLED 为静态文件启用文档页脚。
NOT_FREQUENTLY_HIT URL 尚未频繁请求,无法证明压缩是正当的。
FAIL_TO_COMPRESS 无法创建压缩副本。

详细信息