排查 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 工具的输出:
排查压缩问题
执行以下步骤来排查压缩问题:
在 IIS 6 或 IIS 7 中启用压缩。
在 IIS 管理器中,右键单击“ 网站” 节点,选择“ 属性”,然后选择“ 服务”。
指定压缩文件夹和权限。
IIS 将压缩文件存储在可以配置的文件夹中。 默认情况下,它
%windir%\IIS Temporary Compressed Files
适用于 IIS 6 和%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files
IIS 7。IIS 7) 的IIS_WPG (IIS_IURS必须对此文件夹具有完全控制权限。 使用 进程监视器 排查此类权限问题。
检查 是否在Metabase.xml中启用了压缩。
未在右侧节点的元数据库中启用压缩。 压缩配置有三个元数据库节点:
w3svc/filters/compression/parameters
w3svc/filters/compression/gzip
w3svc/filters/compression/deflate
必须配置
/parameters
节点。 然后,可以配置或/deflate
节点,或同时配置/gzip
这两者。 这意味着仅配置 gzip、deflate 或参数节点将不起作用。 如果配置/parameters
和/gzip
节点,将启用 Gzip 压缩方案。 如果配置/parameters
和/deflate
节点,则将启用 Deflate 压缩方案。 最后,如果配置所有三个节点,将同时启用 GZip 压缩和 Deflate 压缩。检查 IIS 6 的元数据库权限。
默认情况下,
IIS_WPG
具有读取、不安全读取、枚举密钥和写入权限/LM/W3SVC/Filters
。如果权限因意外更改或安全强化而删除,IIS 将无法初始化压缩。
使用 metaacl.vbs 验证和修改 IIS 6 元数据库 ACL。 有关详细信息,请参阅 默认元数据库 ACL。
如果应用程序池标识 (或
IIS_WPG
一般) 组对元数据库密钥 W3SVC 或筛选器没有读取和写入访问权限,则会在适用于 Windows 的企业跟踪中记录失败条件COMPRESSION_DISABLED
, (ETW) 跟踪。ETW 跟踪
IISCompression: STATIC_COMPRESSION_NOT_SUCCESS - IIS has been unsuccessful doing static compression Reason: COMPRESSION_DISABLED
检查是否在 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>
检查要压缩的文件类型是否在 和
/deflate
节点的相应文件扩展名部分中/gzip
列出。使用
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>
注意
必须使用正确的语法配置
HcFileExtensions
或HcScriptFileExtensions
属性。 任何尾随空格或不必要的引号或回车符都将导致属性配置错误。 遗憾的是,如果添加额外的空间 ,adsutil.vbs 不会显示错误,因此需要非常小心。 此外,不能将值复制或粘贴到命令提示符或 metabase.xml文件中, (元数据库直接编辑) ,必须手动键入。检查压缩是否在主级别设置,但是否被子级别的设置替代。
将在 级别启用
w3svc/filters/compression
压缩。 但是,它可能是被网站或应用程序级别的设置所替代。例如,如果在
HcDoDynamicCompression
级别上已设置为TRUE
w3svc/filters/compression
,而默认网站已DoDynamicCompression
设置为FALSE
,则不会对对默认网站的请求做出响应进行动态压缩。检查防病毒程序是否已扫描保存压缩文件的目录。
在运行 IIS 的服务器上启用压缩并从 IIS 压缩目录提供 HTTP 请求时,可能会返回 0 字节文件而不是预期的文件。
注意
仅当启用了 HTTP 静态压缩时,才会看到这些症状。
这是因为 IIS 服务器上运行的防病毒软件正在扫描 IIS 压缩目录。
因此,需要从防病毒软件的扫描列表中排除 IIS 压缩目录。
检查所请求的 URL 是否包含斜杠作为传递给执行 DLL 文件的参数的一部分。
检查 ISAPI 筛选器是否修改请求或响应标头。
ISAPI 正在执行发送操作,并且未将完整的 HTTP 标头集以及实体一起发送到
HTTP_COMPRESSION::DoDynamicCompression
。 由于DoDynamicCompression
不会从 ISAPI 接收所有数据,因此无法压缩响应。 已发现第三方和/或非 Microsoft ISAPI 通过以下方法执行此操作:将标头放在用于实体正文的函数中,或者将实体正文放在用于 HTTP 标头的函数中,或者不提供任何标头。 发生这种情况时,ISAPI 筛选器SF_NOTIFY_SEND_RESPONSE、AddResponseHeaders 或动态压缩将失败。 ISAPI 需要分别将标头和实体放在正确的位置。检查响应状态代码是否不是 200。 在 IIS 6 或 7 中,只有具有 HTTP 200 状态的响应才会被压缩。
不会压缩状态代码为 200 以外的响应。 必须编写 才能
HTTPModule
实现相同的目标。检查请求是否包含
Via: header
,Via headers
指示请求通过代理传入 IIS。许多代理未正确处理压缩标头,并在客户端不应处理压缩数据时向客户端提供压缩数据。 因此,默认情况下,当请求具有 Via 标头时,不允许压缩响应。 可以通过将
HcNoCompressionForProxies
元数据库键设置为 来True
替代此设置。检查请求是否针对静态页面,以及响应是否包含文档页脚。 文档页脚将导致静态压缩失败。
检查静态压缩是否不起作用。 如果在 IIS 的根级别安装了通配符应用程序映射,则可能会发生这种情况。 例如,我们在服务器上为 .html 或 .txt 扩展提供了应用程序映射,这会使 IIS 将 .txt 的请求视为动态请求而不是静态请求,并且由于 .txt 不是动态压缩列表中的扩展,因此不会压缩它。
检查是否存在 IIS 压缩和
Accept-Encoding: identity
字段。根据RFC2616,如果
Accept-Encoding
请求中存在字段,并且服务器无法发送响应(根据Accept-Encoding
标头可接受),则服务器应发送错误响应, (不可接受) 状态代码。 如果请求中没有Accept-Encoding
字段,服务器可能会假定客户端将接受任何内容编码。 在这种情况下,如果“identity”是可用的内容代码之一,则服务器应使用“标识”内容代码,除非它包含其他内容代码对客户端有意义的其他信息。检查是否正在使用 ETW 跟踪来排查 IIS 压缩问题。
Windows (ETW) 事件跟踪是 Windows OS 的一项功能,可用于排查 HTTP 请求问题。
下面是排查 IIS 压缩问题的步骤。
创建名为 IISProviders.txt 的文本文件,并将关注内容放入文件中。”IIS:WWW 服务器“是提供程序名称,0xFFFFFFFE表示所有事件的跟踪,5 表示详细级别。
打开命令提示符,并运行以下命令。
logman start trace compressionTrace -pf IISProviders.txt -ets
重现问题。
运行以下命令以停止跟踪。
logman stop trace compressionTrace -ets
将跟踪转换为文本文件。
跟踪报表将二进制跟踪数据转换为文本,并在执行
tracerpt
命令的目录中生成两个文件:tracerpt compressionTrace.etl
Summary.txt 包含有关跟踪会话的一般详细信息,包括使用了哪些提供程序。
DumpFile.csv 包含文本格式的实际跟踪数据。
读取跟踪文件以查找有用信息。 打开 dumpfile.csv,找到COMPRESSION_NOT_SUCCESS等关键字 (keyword) 。 下面是一个示例:
IISCompression, STATIC_COMPRESSION_NOT_SUCCESS, 0x000008B0, 129744354075770195, 0, 0, {00000000-0000-0000-0700-0060000000bd}, "NO_MATCHING_SCHEME", 0, 0
此错误NO_MATCHING_SCHEME意味着此扩展或 Accept-Encoding 没有压缩方案匹配项。 有关压缩错误的详细列表,请参阅 压缩错误列表。
检查是否使用了用于排查 IIS 压缩问题的 FREB 跟踪。
有关详细步骤,请参阅 在 IIS 7 中使用跟踪排查失败请求问题。
下面是使用 IIS 7 FREB 跟踪排查压缩问题的示例。
压缩错误列表
有关压缩错误的详细列表,请参阅下表。
注意
以下原因适用于 IIS 6 和 IIS 7。
Reason | 说明 |
---|---|
NO_ACCEPT_ENCODING | 客户端未发送 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 | 服务器未配置为压缩此扩展的 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 | 无法创建压缩副本。 |