转自http://www.uigarden.net/chinese/gao-xing-neng-iii

开发出高性能的网站,第三部分:压缩和其他服务器端的技术 - 2005-05-01


作者 Thomas A. Powell 和 Joe Lima

阅读本文英文原文(翻译:刘松涛)
Port80软件授权发表

第一部分 , 我们讲了代码优化的20个技巧,这些代码优化都是针对开发者源代码的;在第二部分 , 我们谈了缓冲控制。我们在此第三部分中,将来和大家一起看看其他的服务器端的技术,来提升网站的速度,我们先来看看HTTP压缩。

什么是HTTP压缩?

HTTP 压缩(或叫HTTP内容编码)作为一种网站和网页相关的标准,存在已久了,只是最近几年才引起大家的注意。HTTP压缩的基本概念就是采用标准的gzip 压缩或者deflate编码方法,来处理HTTP响应,在网页内容发送到网络上之前对源数据进行压缩。有趣的是,在版本4的IE和NetScape中就早 已支持这个技术,但是很少有网站真正使用它。Port80软件公司做的一项调查显示,财富1000强中少于5%的企业网站在服务器端采用了HTTP压缩技 术。不过,在具有领导地位的网站,如Google、Amazon、和Yahoo!等,HTTP内容编码技术却是普遍被使用的。考虑到这种技术会给大型的网 站们带来带宽上的极大节省,用于突破传统的系统管理员都会积极探索并家以使用HTTP压缩技术。

我们可以在浏览器发出的Accept请求的头部看到HTTP内容编码的键值。我们来看看Mozilla Firefox浏览器的这个请求,如下,我们特别注意一下AcceptAccept-LanguageAccept-Encoding,和 Accept-Charset的头(header):

GET / HTTP/1.1
Host: www.port80software.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040206 Firefox/0.8
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

这些个"Accept"值 会被服务器用到,进而决定将适当的内容通过内容协商(Content Negotiation)发回来—这是非常有用的功能,它可以让网站服务器返回不同的语言、字符集、甚至还可以根据使用者的习惯返回不同的技术。关于内容 协商的讨论很多,我们这就不再多讲。我们主要来看看和服务器端压缩有关的一些东西。Accept-Encoding表明了浏览器可接受的除了纯文本之外的内容编码的类型,比如gzip压缩还是deflate压缩内容。

我们下面来看看IE发出的请求headers,我们可以看到类似的Accept-Encoding值:

GET / HTTP/1.1
Host: www.google.com
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)
Accept: image/gif,image/x-xbitmap,image/jpeg,image/pjpeg, application/vnd.ms-excel,application/vnd.ms-powerpoint,application/msword, application/x-shockwave-flash,*/*
Accept-Encoding: gzip,deflate
Accept-Language: en-us
Connection: keep-alive

假设当今主流的每种浏览器都支持gzip和deflate编码(那些不支持的也不会发出Accept-Encoding),我们可以简单的修改一下网站服务器,从而返回压缩内容到这些浏览器上,并返回标准(也就是没有压缩的)内容到其他的浏览器上。在下例中,如果我们的浏览器告诉Google它不接受内容编码,我们会取回3,358字节的数据;如果我们发出Accept-Encoding,再加上应答header告诉我们Content-Encoding: gzip,我们则会取回仅仅1,213字节 。用浏览器的查看源代码功能来看源代码,我们看不出什么差异,但如果使用网络跟踪的话,我们就会发现其响应是不同的。

图一: Google压缩 / 非压缩对比

图一: Google压缩 / 非压缩对比

上例中,虽然文件不大,但是效果依然很明显—压缩后比原来小了74%。再加上我们前面两部分谈到的HTML、CSS、和JavaScript代码优化,Google在提升网站性能上的成果非常惊人—它的一个网页居然可以放在一个TCP响应包里。

虽 然Google在带宽上的考虑也远远超出其他一般的网站,HTTP内容编码进一步让HTML、CSS、和JavaScript等瘦身50%甚至更多。不好 的地方是,HTTP内容编码(词语‘压缩’和‘内容编码’在本文中基本上是一个意思) 基本上针对文本内容很有效,对于图像和其他二进制文件的压缩效果就一般了,有时可能根本没有效果,但总的来说,即使有很多二进制文件的时候,整体上可以瘦 身15%到30%那么多。

HTTP内容编码的服务器端支持

如果你现在认同HTTP压缩的 价值,下一个大问题是:你如何来实施?在Apache网站服务器上,可以使用mod_deflate来进行HTTP内容的编码。在微软的IIS上,就有些 麻烦了。虽然IIS 5可以支持gzip的编码压缩,但实施起来还是超级麻烦,尤其考虑到因为各种浏览器中细微差异来进行各种细致参数调整的时候。所以在IIS 5上,还是要考虑第三方的采用ISAPI过滤器的压缩插件,比如httpZip 就是最好的一种。IIS 6上集成了压缩功能,也更快更灵活,但是还是配置起来比较复杂。ZipEnable 带给我们第一个专为IIS 6集成压缩细致管理的工具—并且还有浏览器兼容情况监测功能。

服务器内容编码的实质

当 实施HTTP压缩时,要平衡考虑一些因素;如果将服务器配置成‘输出’的内容压缩方式,虽然可以降低带宽的使用,但同时却增加了CPU的开销。多数情况 下,这不是什么大问题,尤其当网站服务器所作工作很少的时候。不过,在网络浏览很繁重的网站服务器上,运行相当多的动态内容就可能会达到CPU工作的极 限,这时再进而进行压缩的话,CPU可能会超负荷运行了。通过添加而外的服务器硬件资源,当然可能会减轻这种问题,并让我们享受通过压缩而节省下来的带 宽, 但最后带宽和CPU的问题还是要看哪个成本更高。

说到底,系统管理员和网站开发者是否对HTTP的压缩有兴趣,还是要看最 后的效果如何。当我们明显的发现带宽的负载下来了,那么访问者也可能会明显感觉转载网页的速度慢了。因为,压缩产生和解压缩会带来的CPU负载, TTFB (time to first byte)也通常会增加,这样浏览器渲染网页的速度也会降下来,但这还算是很好的平衡,因为数据压缩后传输的包变小了、变少了,提交的速度会变快,这个快 速回补偿网页渲染的慢速。然而,对于宽带用户来说,这样的改善可能就不明显了。不过,这两种情况下,对于网站建设者来说,都可以节省一些网络上的投资。当 然,如果可感知的反应时间对某网站来说是主要目标,并且网站的访问者很多都还使用拨号上网,那么本文的第二部分钟所讲的缓冲控制就是比较好的性能提高策 略。

最后,HTTP内容编码的另一个潜在问题是和由脚本产生的网页带来的服务器负载有关的,比如PHP和ASP。在此种情况下, 主要的问题是,网页内容每次请求可能会被再压缩,这样就会给服务器增加更多的负载(相对压缩静态内容来说)。如果,网站中所有的网页都是在请求时生成的 话,那么使用HTTP内容编码就得格外小心了。还好,很多商业上使用的压缩插件,直到如何对内容进行缓冲,但业余(较便宜的)的压缩工具可能就没有这些特 性了。

动态网页:立即生成,还是稍后生成?

有趣的是,很多的开发者都是在网站被访问时开 始动态的生成很多甚至全部他们网站的网页。比如,http://www.domain.com/article.php?id=5就是一个通用的URL, 它暗示了某个网页是由数据库查询时或填充模版生成的。这种常用方法的问题是,在很多情况下,在请求时间生成一个网页是pointless的,因为很多时候 这个主要的静态的(所谓的静态的动态网页、或脚本网页),其内容很长时间也不变化,这显然对于提高网页装载速度没有什么帮助。实际上,在一个高负荷的网站 这种方式会严重的降低服务期的性能。

要避免不必要的动态网页的生成,有一个方法是,每次有变化时,则预先生成有内容的静态. html网页。如果这些生成的.html网页,还是经过了代码优化(在本文第一部分中过这些描述方法),则更好。这不仅会让服务器交付这些网页更快变得更 容易,而且这些技术还会使搜索引擎更友好。

不幸的是,在很多情况下,简单的生成动态的HTML网页并不太容易,也为很多网页只有 在网页被访问时才能够正确的生成动态内容。在这种情况下,你最好是对网页进行‘烘焙’生成快速执行的形式。在ASP .NET的情况下,这种形式则是二进制代码,在服务器端执行的特别快。不好的地方是,在用户访问之前,服务器需要先执行这些网页强制执行这些字节代码。还 好,在ASP .NET 2.0中,这些问题将得到改善。在PHP中,一些诸如Zend等的优化软件是不错的投资。

对于提交静态 和动态网页、或者HTML和图像的不同需要来说,考虑一下针对物理服务器或其他的硬件上的加速可能,也是比较明智的选择。为了网页加速而加强硬件方面的投 入的另一个方法是专业化—不同的部件进行不同的工作,这样产生出最大的效率。虽然,本文是从代码和网站服务器校对来说明如何提高网站的性能的,我们也不妨 讨论讨论其他相关的元素。

对网站服务器进行涡轮增压

加速网站要考虑的一个重点是服务器软 件和服务器硬件。先谈软件,网站系统管理员不太可能来回因为易用性问题、性能问题、安全问题等在Apache和IIS之间切换来切换去。简言之,网站服务 器和其底层的操作系统之间的关系错综复杂、互相影响,再进行系统或服务迁移则更是繁重且有风险的工作。所以,你如果真的考虑放弃一种网站服务器而使用另一 种的话,你必须严肃认真的好好考虑这个问题;而如果速度是考虑的第一要素的话,建议你考虑一下Zeus。

再谈硬件,如果要考虑升 级硬件,则先仔细分析一下服务器上的主要任务。在静态网站上,主要的工作是调整网络连接和把文件从磁盘拷贝到网络上。要加速这样类型的网站,你得把注意力 放在高速硬盘子系统和高速网络子系统上,另外还得有足够多的内存来处理并发请求。实际上,你可能得给服务器添加大量的内存,从而为经常使用的对象尽可能的 增加内存缓冲来减轻磁盘的存取。有趣的是,CPU的速度在这里却不是十分关键。虽然不能否认CPU对网站的整体性能有影响,但瓶颈主要发生在磁盘上。但 是,当网站处理动态网页和静态网页差不多一样多的时候,处理器就显得很关键了,但即便如此高速磁盘或双网卡还是更有效一些。另一种情况下,除了要处理动态 网页,还要处理其他占用CPU的操作(比如SSL和HTTP压缩等)的时候,CPU就显得十分关键了。换句话说,要加速网站服务时,服务器具体所作的工作 决定着什么类型的硬件资源更需要增强。

当你没有那么多增加服务器硬件或软件的预算时,还有一些物美价廉的解决方法。比如,你可以 对服务器的TCP/IP设置进行优化,这样依赖TCP/IP网络的HTTP便可以最优运行。TCP/IP的设置优化里,有一项是TCP的接受窗口,可以把 它调整成最适合应用或者最适合网络连接的,或者是针对确保TCP连接的一些参数(如ACK或TCP_NODELAY等)进行调整,根据具体情况设置成使用 或不使用。还有一些参数,比如TIME_WAIT时间等,也是可以进行调整的。但要记住,不管怎么调整这些网站服务或操作系统的参数,都必须进行真实的加 载试验以验证你的调整会不会反而减慢用户访问的服务或带来新的问题。此外,一定要弄懂这些参数之后,再进行调整。

通过分工进行加速

网站加速还可以考虑的一个出发点是,不同的网站内容可能会拥有不同的提交特性。考虑到不同的内容,其特性也不同,我们可以用多个服务器,每个服务器来执行不同的内容处理,这样可能比用服务器池(server farm)中的每一个服务来处理同样的任务要好得多。

我 们来看一个分工进行加速的简单例子。当你的商务网站给购物车或外部网使用SSL加密的时候,你会发现当有多个用户同时访问的时候,SSL加密带来 HTTPS段的明显负载会使你的服务器的性能会急剧下降。这种情况下,把流量分配给另一台服务器,其意义就十分明显了。比如,把你的主站点放在 www.domain.com上,把结账的处理部分放在shop.domain.com上。这个shop.domain.com就是一个专门处理SSL流 量的服务器,可能会用到SSL加速卡。采取分工的方式,可以让你专心处理结账的用户的SSL流量,而不至于像以往SSL的处理会导致服务器整体性能的下 降。对于图像和其他重量级的二进制的比如PDF文档或.exe文档,服务器处理其下载可能要花些力气,这些连接通常持续的时间比一般的连接都长,会消耗大 量宝贵的TCP/IP资源。进而,对于这些媒体资源(PDF、.exe、图像等)的处理,我们也并不需要把它们和文本资源(HTML、CSS和 JavaScript等)等同对待处理。在这种情况下,让处理文本资源的服务器有高性能的CPU,让处理媒体资源的服务器有大带宽,是有的放矢的解决之 道。

分工还可以进一步应用到网页的生成上。我们可以考虑把生成网页的工作单独放在一个服务器上,把处理静态内容的工作放在另一个 服务器上。现在已然有很多网站是采取这样的模式了,这其中很多网站会使用一个叫做Squid的反向代理(reverse proxy)。在设置过程中,代理服务器专门提供静态的内容,速度很快;而后台的服务器则可以专心处理在访问时才会产生的动态内容。缓冲控制策略和规则, 我们在第二部分中谈到过,在这时的设置过程中就显得十分重要了;我们得确保代理服务器的缓冲中储存的内容在共享缓冲中是安全的。

为了争夺市场而提速

我 们刚才谈的那些东西主要是一些低成本的加速技术,在我们本文即将结束的时候,我们来看看一些需要软硬件成本很高但收益可观的方法。目前市场上提供有一些需 要花些钱的独特加速设备,它们可以进行比如网络连接分流、压缩、缓冲、和其他等技术,从而达到加速的目的。 如果你不在乎投资高带宽的话,这些解决方案就十分有效,但是大多数的网站还是更喜欢我们先前介绍过的物美价廉的方法,比如代码优化、缓冲、和HTTP编码 等。

就算你有很多资金,可以投资一个服务器池(server farm)、并添加最高档的加速设备,也使用压缩和缓冲技术等,但你还是会最后达到一个极限。要想进一步再提速,还有最后一招:把内容放在离访问者最近的 地方,有可能的话,在那个地方再实施上述各类技术(如压缩、缓冲等)。你肯定注意过,有些网站提供镜像服务器等,这样世界各地的访问者就可以就近访问所需 内容。不过,还有比这个更有地理分布意义的方法,并且可以透明的让访问者使用。内容分发网络(Content Distribution Network – CDN),比如Akamai,就可以让我们把重型内容(如图象和其他二进制内容等)搬移到离访问者更近的地方,这样通过内容分发网站在世界各地的边缘缓 冲,访问者访问起来就会更快。这种方式带来了性能上极大提高,目前世界级的一些大网站都在使用。虽然这算不上是经济实用的方法,但作为这些方法的最后补 充,放在这里以飨读者。

Thomas A. Powell 是PINT公司的创始人,也是加州大学San Diego分校计算机科学系的讲师,以及一些网页开发书籍的作者,其所著书目包括《HTML & XHTML: The Complete Reference》和 《JavaScript: The Complete Reference》等。

Joe Lima 是Port80软件公司的首席构架师(architect),同时教授UCSD 扩展的服务器技术。

Port80软件公司
Port80 Software, Inc. 是微软 Internet Information Services (IIS) 网络服务的领先的开发商. 公司同时提供w3compiler, 一套优化代码的桌面应用软件。Port80 Software 是微软认证合作商(MCP ISV)。它位于San Diego, CA. 更多信息请见公司网站 www.port80software.com.