作者:Shoeb Ilyas Bhaldar 和 Mike Laing
此疑难解答中使用的工具:
- Fiddler
- 网络监视器
- 进程监视器
- 元数据库 ACL
- IIS 6 ETW 跟踪
- IIS 7 FREB 跟踪
此材料仅供参考。 Microsoft 不做任何明示或暗示的担保。
概述
为 IIS6/7 Web 应用程序启用 HTTP 压缩是提高站点性能的一种方式。
遗憾的是,IIS 管理员 GUI 不会公开完全管理它所需的许多压缩属性。 它只允许我们打开或关闭它。 因此,请务必注意,若要将其完全配置为 http 压缩,需要使用 IIS 管理器以外的工具编辑metabase.xml。 我们使用的最常用工具是adsutil.vbs,该工具包含在 IIS 安装中
此疑难解答将帮助你配置压缩,确定 IIS 压缩 & 在 IIS6 和 IIS 7.x 中可能不起作用的常见原因
验证
确定压缩是否正常工作
确定 IIS 服务器是否发送压缩响应的唯一方法是分析客户端请求/服务器响应的网络跟踪。 来自客户端的请求需要包含以下 HTTP 请求标头:
HTTP: Accept-Encoding =gzip, deflate
这会告知服务器客户端支持压缩,并接受压缩的响应。 返回时,来自服务器的压缩响应将包含以下 HTTP 响应标头和一个值:
HTTP: Content-Encoding = gzip
压缩不起作用时 Fiddler 输出:
疑难解答
在 IIS6/IIS7 中启用压缩: 在 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 位置配置是 *必需*。 然后,需要在 /gzip *或* /deflate、*或两者中配置。 这意味着在 /gzip 处进行配置将不起作用,而仅 /deflate 将不起作用,而仅 /parameters 将不起作用。 但是,在 /parameters 和 /gzip 上配置将启用 Gzip 压缩方案。 配置 /parameters 和 /deflate 将启用 Deflate 压缩方案。 最后,配置所有三者都将启用 GZip 压缩和 Deflate 压缩。
检查 IIS 6 的元数据库权限: 默认情况下,IIS_WPG具有对 /LM/W3SVC/Filters 的读取、不安全读取、枚举密钥和写入权限。
如果由于意外更改或安全强化而删除了权限,IIS 将无法初始化压缩。
使用metaacl.vbs验证和修改 IIS 6 元数据库 ACL。 (
https://www.microsoft.com/download/en/details.aspx?displaylang=en&id=4899
)如果应用程序池标识 (或IIS_WPG组通常) 没有对元数据库密钥 W3SVC/Filters 的读取和写入访问权限,则会在 Windows (ETW) 跟踪的企业跟踪中记录COMPRESSION_DISABLED失败条件。
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) 。
例如,若要使用 adsutil.vbs 在 /parameters 节点上设置动态压缩,请运行以下命令:
cscript.exe adsutil.vbs SET w3svc/filters/compression/parameters/HcDoDynamicCompression TRUE
该命令的输出如下所示:
HcDoDynamicCompression : (BOOLEAN) True
在 IIS7 中:
<system.webServer> <urlCompression doStaticCompression="true" doDynamicCompression="true" /> </system.webServer>
检查要压缩的文件类型是否列在 /gzip 和 /deflate 节点的相应文件扩展名部分中: 使用 HcDoDynamicCompression 和/或 HcDoStaticCompression 键启用压缩后,必须确保告知 IIS 实际压缩哪些文件类型。 默认情况下,我们将压缩 htm、html 和 txt 进行静态压缩,以及用于动态压缩的 asp、dll 和 exe。 如果需要压缩不同的文件类型(例如 aspx),则需要将其添加到 /gzip 和/or /deflate 节点中的相应文件扩展名部分,具体取决于所使用的压缩类型。 对于静态文件压缩 ((如 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 在 w3svc/filters/compression 级别设置为 TRUE,并且对于默认网站将 DoDynamicCompression 设置为 FALSE,则不会对对默认网站请求的响应进行动态压缩。
检查防病毒程序是否已扫描存储压缩文件的目录:
在运行 Internet Information Services 的服务器上启用压缩 (IIS) ,并从 IIS 压缩目录提供 HTTP 请求时,可能会返回 0 字节文件,而不是预期文件。
注意
如果启用了 HTTP 静态压缩,则只能看到这些症状。
这是因为 IIS 服务器上运行的防病毒软件正在扫描 IIS 压缩目录。
因此,需要从防病毒软件的扫描列表中排除 IIS 压缩目录。
检查所请求的 URL 是否包含斜杠,作为传递给执行 DLL 文件的参数的一部分。
ISAPI 筛选器修改请求/响应标头:
ISAPI 正在执行发送操作,并且未将完整的 HTTP 标头集与实体一起发送到 HTTP_COMPRESSION::D oDynamicCompression。 由于 DoDynamicCompression 不会从 ISAPI 接收它应接收的所有数据,因此无法压缩响应。 第三方和非 Microsoft ISAPIs 通过将标头置于用于实体正文的函数中或针对 HTTP 标头的函数中的实体正文,或者不提供任何标头来执行此操作。 发生这种情况时,ISAPI 筛选器SF_NOTIFY_SEND_RESPONSE或 AddResponseHeaders 或动态压缩等操作将失败。 ISAPI 需要分别将标头和实体放在正确的位置。
响应状态代码不是 200。 在 IIS 6/7 中,只有具有 HTTP 200 状态的响应才会压缩。
是的,这两个 IIS6 & IIS 7.x 中都是如此,不会压缩包含 200 以外的状态代码的响应。 我们必须编写 HTTPModule 才能实现相同的目的。
如果请求包含 Via: 标头: Via 标头指示请求通过代理传入 IIS。 许多代理不会正确处理压缩标头,并且当客户端不应处理压缩数据时提供给客户端,因此默认情况下,当请求具有 Via 标头时,我们不允许压缩响应。 可以通过将 HcNoCompressionForProxies 元数据库密钥设置为 True 来替代此功能。
请求适用于静态页面,响应包含文档页脚。 文档页脚将导致静态压缩失败。
静态压缩不起作用: 如果在 IIS 中根级别安装了通配符应用程序映射,则可能会发生此情况。 例如, 我们在服务器上具有.html或.txt扩展的应用程序映射) ,这会使 IIS 将请求视为动态请求 .txt而不是静态请求,并且由于.txt不是动态压缩列表中的扩展,因此不会进行压缩。
IIS 压缩和“Accept-Encoding: identity”:
根据 RFC2616:
“如果请求中存在Accept-Encoding字段,并且服务器无法根据Accept-Encoding标头发送可接受的响应,则服务器应发送错误响应,并显示 406 (”不可接受) 状态代码”。 如果请求中不存在Accept-Encoding字段,服务器 MAY 假定客户端将接受任何内容编码。 在这种情况下,如果“identity”是可用内容编码之一,则服务器应使用“标识”内容编码,除非它具有其他信息,即其他内容编码对客户端有意义。
使用 ETW 跟踪排查 IIS 压缩问题
Windows (ETW) 事件跟踪是 Windows 操作系统的一项功能,可用于排查 HTTP 请求的问题。
下面是排查 IIS 压缩问题的步骤。
创建名为IISProviders.txt的文本文件,并将关注内容放入文件中。IIS:WWW Server“是提供程序名称,0xFFFFFFFE表示所有事件的跟踪,5 表示详细级别。
“IIS: WWW Server” 0xFFFFFFFE 5 有关详细信息,请参阅 IIS 提供程序: https://technet.microsoft.com/library/cc758221(v=ws.10).aspx
打开命令窗口,然后运行以下命令:
logman start trace compressionTrace -pf IISProviders.txt -ets
再现此问题。
运行以下命令以停止跟踪。
Logman stop trace compressionTrace -ets
将跟踪转换为文本文件。
跟踪报表将二进制跟踪数据转换为文本,并在执行 tracerpt 命令的目录中生成两个文件:
tracerpt compressionTrace.etl
Summary.txt 包含有关跟踪会话的一般详细信息,包括使用哪些提供程序。
DumpFile.csv 包含文本格式的实际跟踪数据。
读取跟踪文件以查找有用的信息。 打开dumpfiles.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 没有压缩方案匹配。 有关压缩错误的详细列表,请参阅附录中的表。
使用 FREB 跟踪排查 IIS 压缩问题
与 ETW 跟踪相比,IIS 7 FREB 跟踪更容易。 有关详细信息步骤,请参阅本文。
下面是使用 IIS 7 FREB 跟踪排查压缩问题的示例。
有关压缩错误的详细列表,请参阅附录中的表。
附录:
表 1:原因适用于 IIS 6 和 IIS 7
原因 说明 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 服务器未配置为压缩此扩展的内容类型 HEADERS_SENT_TWICE 为同一响应发送两次标头 NO_HEADER_SENT 实体正文发送之前未发送标头 NOT_SUCCESS_STATUS 响应状态代码未成功 (200) ALREADY_CONTENT_ENCODING 响应中已存在内容编码 表 2:原因仅适用于 IIS 7。
原因 说明 FOOTER_ENABLED 为静态文件启用文档页脚 NOT_FREQUENTLY_HIT URL 请求的频率不够大,无法证明压缩是正当的 FAIL_TO_COMPRESS 无法创建压缩副本