最佳实践 4:使用 IIS 压缩提高 ASP.NET 网站的带宽性能






4.87/5 (70投票s)
最佳实践 4:使用 IIS 压缩提高 ASP.NET 网站的带宽性能。
已更新 .NET 最佳实践编号:1、2、3、5 和视频的链接。
目录 | 使用 finalize/dispose 模式提高垃圾回收器性能
|
引言
带宽性能是每个网站的关键要求之一。如今,网站的主要成本不是硬盘空间,而是带宽。因此,在可用带宽上最大化传输数据量变得非常关键。在本文中,我们将探讨如何使用 IIS 压缩来提高带宽性能。
IIS 压缩如何工作?
注意:本文中的所有示例均使用 IIS 6.0。我们之所以使用 IIS 6,仅仅是因为 7.0 还没有那么普及。
在深入探讨 IIS 压缩的工作原理之前,让我们先尝试理解 IIS 通常是如何工作的。假设用户请求一个大小为 100 KB 的“Home.html”页面。IIS 通过将 100 KB 的 HTML 页面通过网络传输到最终用户浏览器来响应此请求。
当 IIS 启用压缩后,事件顺序如下改变:
GET /questpond/index.html HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg,
application/x-shockwave-flash, application/vnd.ms-excel */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0
Host: www.questpond.com
Connection: Keep-Alive
- 用户向 IIS 服务器请求页面。在请求页面的同时,浏览器还会发送它支持的压缩类型。下面是一个发送到浏览器的简单请求,表明它支持“gzip”和“deflate”。我们使用了 fiddler(http://www.fiddler2.com/fiddler2/version.asp)来获取请求数据。
- 根据浏览器发送的压缩类型支持,IIS 会压缩数据并通过网络发送给最终浏览器。
- 然后浏览器解压缩数据并在浏览器中显示。
压缩基础知识:Gzip 和 Deflate
IIS 支持两种压缩:Gzip 和 Deflate。两者大同小异,其中 Gzip 是 Deflate 的一个扩展。Deflate 是一种压缩算法,它结合了 LZ77 和 Huffman 编码。如果您有兴趣阅读更多关于 LZ77 和 Huffman 的内容,可以参考 http://www.zlib.net/feldspar.html。
Gzip 基于 Deflate 算法,并在 Deflate 有效载荷中添加了额外的头部。
下面是添加到 Deflate 有效载荷数据的头部详细信息。它以一个 10 字节的头部开始,其中包含版本号和时间戳,后面是文件名的可选头部。最后是实际的 Deflate 压缩有效载荷和 8 字节的校验和,以确保数据在传输过程中不会丢失。
Google、Yahoo! 和 Amazon 使用 gzip,因此我们可以放心地假设大多数浏览器都支持它。
启用 IIS 压缩
到目前为止,我们已经学习了足够的理论来理解 IIS 压缩。现在让我们动手实践,看看如何实际启用 IIS 压缩。
步骤 1:启用压缩
第一步是在 IIS 上启用压缩。因此,右键单击网站 -> 属性,然后单击“服务”选项卡。要启用压缩,我们需要从 IIS 网站属性的“服务”选项卡中勾选以下两个文本框。下图显示了这两个复选框的位置。
步骤 2:启用 metabase.xml 编辑
IIS 的元数据来自“Metabase.xml”,该文件位于“%windir%\system32\inetsrv\”。为了使压缩正常工作,我们需要对此 XML 文件进行一些更改。为了对该 XML 文件进行更改,我们需要指示 IIS 授予我们编辑权限。因此,右键单击您的 IIS 服务器根目录 -> 转到属性,然后勾选“启用直接 metabase 编辑”复选框,如下图所示。
步骤 4:设置压缩级别和扩展名类型
下一步是设置压缩级别和扩展名类型。压缩级别可以定义为 0 到 10 之间,其中 0 表示轻度压缩,10 表示最高级别的压缩。此值使用 HcDynamicCompressionLevel
属性指定。有两种压缩算法:“deflate”和“gzip”。此属性需要在两种算法中都指定,如下图所示。
我们还需要指定哪些文件类型需要被压缩。HcScriptFileExtensions
帮助我们指定这一点。对于当前场景,我们指定需要压缩 ASPX 输出,然后再将其发送给最终浏览器。
步骤 5:它真的有效吗?
完成上述四个步骤后,就可以查看压缩是否真的有效了。因此,我们将创建一个简单的 C# ASP.NET 页面,该页面将循环“10000”次并将某种输出发送到浏览器。
protected void Page_Load(object sender, EventArgs e)
{
for (int i; i < 10000; i++)
{
Response.Write("Sending huge data" + "<br>");
}
}
为了看到压缩前和压缩后的区别,我们在运行 ASP.NET 循环页面时运行 fiddler 工具。您可以从 http://www.fiddler2.com/fiddler2/version.asp 下载 fiddler。
下图显示了 fiddler 在未压缩和压缩时捕获的数据。未压缩时数据为“80501 字节”,压缩后为“629 字节”。我确信从带宽的角度来看,这是一个巨大的性能提升。
0, 1, 2, 3, 4…10 IIS 压缩级别
在前一节中,我们将 HcDynamicCompressionLevel
设置为 4。压缩级别值越高,数据大小越小。随着压缩级别的提高,缺点是 CPU 使用率更高。一个大的挑战是找出最优的压缩级别。这取决于许多因素:数据类型、负载等。在接下来的部分中,我们将尝试为不同场景推导出最佳的压缩级别。
IIS 压缩优化的三个考虑点
许多开发人员只是启用 IIS 压缩并使用以下默认值。但是默认值并不适用于所有环境。它取决于许多其他因素,例如您的站点提供的原始内容类型。如果您的站点仅包含静态 HTML 页面,那么压缩级别将与提供大部分动态页面的站点的压缩级别不同。
压缩选项 | 文件类型 | 默认配置 |
压缩的文件类型 | 静态 | .txt、.htm 和 .html |
动态 | ||
压缩方案 | 静态 | Gzip 和 Deflate |
动态 | Gzip 和 Deflate | |
压缩级别 | 静态 | 10 |
动态 | 0 |
如果您的站点仅提供已压缩的数据,如“JPEG”和“PDF”,则可能不建议启用压缩,因为 CPU 使用率会大幅增加,但压缩收益很小。另一方面,我们也需要平衡压缩与 CPU 使用率。我们增加压缩级别的程度越高,CPU 资源消耗得越多。
不同类型的数据需要设置为不同的 IIS 压缩级别以进行优化。在下一节中,我们将处理不同的数据类型,用不同的压缩级别进行分析,并观察 CPU 使用率如何受到影响。下图显示了不同数据类型及其文件类型示例。
静态数据压缩
让我们从最简单的开始,即静态内容类型,如 HTML 和 HTM。如果用户请求 IIS 的静态页面并启用了压缩,IIS 会压缩文件并将其放入“%windir%\IIS Temporary Compressed Files”目录。
下面是一个显示压缩文件夹快照的简单屏幕。压缩仅在第一次发生。在后续调用时,将从压缩文件目录中提取相同的压缩数据。
以下是我们针对大小从 100 KB 到 2048 KB 的 HTML 文件进行的一些示例读数。我们将压缩级别设置为“0”。
实际 KB | 压缩后 KB |
100 | 24 |
200 | 25 |
300 | 27 |
1024 | 32 |
2048 | 41 |
压缩级别设置为“0” |
您可以轻松看到,即使启用了最低压缩级别,压缩率也几乎是五倍。
由于压缩仅在第一次发生,我们可以放心地将压缩级别设置为“10”。第一次我们会看到巨大的 CPU 使用率,但与压缩收益相比,后续调用的 CPU 使用率会很小。
动态数据压缩
动态数据压缩与静态压缩略有不同。动态压缩会在每次请求页面时发生。我们需要在 CPU 使用率和压缩级别之间取得平衡。
为了找到优化的压缩级别,我们进行了一个小型实验,如下所示。我们选取了五种大小从 100 KB 到 2 MB 的文件。然后,我们更改了每个文件大小的压缩级别从 0 到 10,以检查数据的压缩程度。以下是压缩后的数据读数(以字节为单位)。
文件大小 | |||||
压缩 关卡 | 100 KB | 200 KB | 300 KB | 1 MB | 2 MB |
0 | 32,774 | 35,496 | 37,699 | 52,787 | 109,382 |
1 | 30,224 | 32,300 | 34,104 | 46,328 | 92,813 |
2 | 29,160 | 31,004 | 32,673 | 43,887 | 87,033 |
3 | 28,234 | 29,944 | 31,628 | 42,229 | 83,831 |
4 | 26,404 | 27,655 | 29,044 | 34,632 | 44,155 |
5 | 25,727 | 26,993 | 28,488 | 33,678 | 42,395 |
6 | 25,372 | 26,620 | 28,488 | 33,448 | 41,726 |
7 | 25,340 | 26,571 | 28,242 | 33,432 | 41,678 |
8 | 25,326 | 26,557 | 28,235 | 33,434 | 41,489 |
9 | 24,826 | 26,557 | 28,235 | 33,426 | 41,490 |
10 | 24,552 | 25,764 | 27,397 | 32,711 | 42,610 |
以上读数没有显示任何特定内容,有点混乱。因此,我们通过绘制上述数据的图表,找到了最佳点。您可以看到,即使将压缩级别从 4 增加到 10,压缩大小也没有变化。我们在 2 到 3 个不同的环境中进行了实验,结果总是指向值“4”,即最佳点。
我们从中得出的结论是,将动态数据页面设置为压缩级别“4”是一个优化的设置。
压缩文件和压缩
压缩文件是指已经压缩过的文件。例如,JPEG 和 PDF 等文件已经压缩过。因此,我们通过对 JPEG 压缩文件进行了一项小测试,以下是我们的读数。应用 IIS 压缩后,压缩文件的大小变化不大。
实际压缩文件大小 | IIS 压缩后的文件大小 |
100 | 102 |
220 | 210 |
300 | 250 |
1024 | 980 |
2048 | 1987 |
当我们绘制图表时,您会看到压缩的收益非常小。我们可能会消耗更多的 CPU 处理器资源,而压缩方面却没有任何收益。
因此,我们可以从压缩文件中得出的结论是,对于 JPEG 和 PDF 等已压缩文件类型,可以禁用压缩。
CPU 使用率、动态压缩和负载测试
动态数据的一个重要考虑因素是优化 CPU 使用率、压缩级别和服务器负载。
我们使用 WCAT 进行压力测试,模拟 100 个并发用户。对于从 100 KB 到 2 MB 的文件大小,我们记录了每个压缩级别的 CPU 使用率。我们使用性能计数器记录了 W3WP 进程的处理器时间。要添加此性能计数器,您可以转到进程 -> 选择处理器时间 -> 从实例中选择 w3wp.exe。
文件大小 | |||||
压缩 | 100 KB | 200 KB | 300 KB | 1 MB | 2 MB |
0 | 1.56 | 1.56 | 1.56 | 4.69 | 4.00 |
1 | 1.56 | 1.56 | 1.56 | 4.69 | 4.00 |
2 | 1.56 | 1.56 | 1.56 | 4.69 | 4.30 |
3 | 1.56 | 1.56 | 1.56 | 4.69 | 4.63 |
4 | 1.56 | 1.56 | 1.56 | 4.69 | 6.25 |
5 | 3.00 | 2.00 | 1.56 | 4.69 | 7.81 |
6 | 3.45 | 2.40 | 3.13 | 4.69 | 9.38 |
7 | 4.00 | 3.00 | 5.00 | 6.25 | 43.75 |
8 | 5.60 | 3.50 | 8.00 | 15.62 | 68.75 |
9 | 6.00 | 5.00 | 9.00 | 25.00 | 87.50 |
10 | 7.81 | 6.25 | 10.94 | 37.50 | 98.43 |
如果我们绘制上述数据的图表,我们会发现最佳点是 6。直到 IIS 压缩级别为 6,CPU 使用率都没有受到真正影响。
TTFB 和压缩级别
TTFB,也称为首次字节响应时间,表示在收到响应的第一个字节之前经过的毫秒数。我们还对 1MB 和 2MB 的动态页面进行了小实验,使用了不同的压缩级别。然后我们测量了每个压缩级别和文件大小组合的 TTFB。WCAT 用于测量 TTFB。
文件大小(MB) | ||
压缩 | 1 | 2 |
0 | 8.00 | 9.00 |
1 | 8.00 | 9.00 |
2 | 8.00 | 9.00 |
3 | 8.00 | 9.00 |
4 | 8.00 | 9.00 |
5 | 9.00 | 9.00 |
6 | 12.00 | 17.00 |
7 | 16.00 | 18.00 |
8 | 19.00 | 19.00 |
9 | 22.00 | 37.00 |
10 | 29.00 | 47.00 |
当我们绘制上述数据时,我们得到了“5”作为最佳值。直到值达到“5”时,TTFB 保持不变。
WCAT 输出用于 TTFB 测量的截图
IIS 7.0 和 CPU 限制
以上所有实验和结论均基于 IIS 6.0。IIS 7.0 有一个非常重要的属性,即 CPU 限制(CPU roll-off)。CPU 限制充当一个切断网关,防止 CPU 资源被无限消耗。
当 CPU 使用率超过某个级别时,IIS 将停止压缩页面;当 CPU 使用率降至另一级别以下时,它将重新开始。这由 staticCompressionEnableCpuUsage
和 dynamicCompressionDisableCpuUsage
属性控制。它就像一个安全阀,这样您的 CPU 使用率就不会突然飙升。
结论
- 如果文件已压缩,则不要对这些文件启用压缩。我们可以安全地禁用 EXE、JPEG、PDF 等文件的压缩。
- 对于静态页面,可以将压缩级别设置为 10,因为压缩仅发生一次。
- 对于动态页面,压缩级别范围可以为“4”到“6”,具体取决于服务器环境和配置。判断哪种压缩级别最合适的最佳方法是执行本文中所述的 TTFB、CPU 使用率和压缩测试。
如果您想进行一些初步的验证,请参考这篇文章:http://weblogs.asp.net/owscott/archive/2009/02/22/iis-7-compression-good-bad-how-much.aspx。我同意我的结果与 Scott 的不完全匹配,但我认为我们在同一战线上。
IIS 压缩的一些已知问题
以下是 IIS 压缩的一些已知问题
我其他的 .NET 最佳实践文章
- .NET 最佳实践 1:在本文中,我们讨论了如何查找 .NET 中的高内存消耗区域。您可以在 https://codeproject.org.cn/KB/aspnet/BestPrctice1.aspx 阅读相关内容。
- .NET 最佳实践 2:在本文中,我们讨论了如何使用 finalize / dispose 模式来提高性能。https://codeproject.org.cn/KB/aspnet/DONETBestPracticeNo2.aspx
- .NET 最佳实践 3:如何使用性能计数器从 .NET 应用程序收集性能数据 https://codeproject.org.cn/KB/aspnet/DOTNETBestPractices3.aspx
- .NET 最佳实践 5:如何检测 .NET 应用程序中的内存泄漏 BestPractices5.aspx
感谢,感谢,再感谢
- 本文的所有灵感均来自 Scott Forsyth 关于 IIS 压缩的文章。您可以说我只是创建了一个更详细的新版本:http://weblogs.asp.net/owscott/archive/2009/02/22/iis-7-compression-good-bad-how-much.aspx
- 感谢 Jimmie 提供了性能计数器和其他 IIS 压缩的详细信息:http://blogs.msdn.com/jimmiet/archive/2009/06/07/iis-6-0-compression.aspx
- 我还从微软的这篇文章中获取了一些内容:http://technet.microsoft.com/hi-in/library/bb742379(en-us).aspx。
扩展阅读链接
- http://www.zlib.net/feldspar.html
- http://www.15seconds.com/Issue/020314.htm
- http://blogs.msdn.com/jimmiet/archive/2009/06/07/iis-6-0-compression.aspx
- http://www.fiddler2.com/fiddler2/version.asp
- http://technet.microsoft.com/hi-in/library/bb742379(en-us).aspx
- http://weblogs.asp.net/owscott/archive/2009/02/22/iis-7-compression-good-bad-how-much.aspx
- http://www.codinghorror.com/blog/archives/000059.html
- http://blogs.microsoft.co.il/blogs/yevgenif/archive/2009/02/08/web-performance-enable-data-compression-on-iis-6-0-server.aspx
如需进一步阅读,请观看以下面试准备视频和分步视频系列。