開發(fā)出高性能的網(wǎng)站,第三部分:壓縮和其他服務(wù)器端的技術(shù) - 2005-05-01
作者 Thomas A. Powell 和 Joe Lima
在第一部分 , 我們講了代碼優(yōu)化的20個(gè)技巧,這些代碼優(yōu)化都是針對(duì)開發(fā)者源代碼的;在第二部分 , 我們談了緩沖控制。我們?cè)诖说谌糠种校瑢砗痛蠹乙黄鹂纯雌渌姆?wù)器端的技術(shù),來提升網(wǎng)站的速度,我們先來看看HTTP壓縮。
什么是HTTP壓縮?
HTTP 壓縮(或叫HTTP內(nèi)容編碼)作為一種網(wǎng)站和網(wǎng)頁相關(guān)的標(biāo)準(zhǔn),存在已久了,只是最近幾年才引起大家的注意。HTTP壓縮的基本概念就是采用標(biāo)準(zhǔn)的gzip 壓縮或者deflate編碼方法,來處理HTTP響應(yīng),在網(wǎng)頁內(nèi)容發(fā)送到網(wǎng)絡(luò)上之前對(duì)源數(shù)據(jù)進(jìn)行壓縮。有趣的是,在版本4的IE和NetScape中就早 已支持這個(gè)技術(shù),但是很少有網(wǎng)站真正使用它。Port80軟件公司做的一項(xiàng)調(diào)查顯示,財(cái)富1000強(qiáng)中少于5%的企業(yè)網(wǎng)站在服務(wù)器端采用了HTTP壓縮技 術(shù)。不過,在具有領(lǐng)導(dǎo)地位的網(wǎng)站,如Google、Amazon、和Yahoo!等,HTTP內(nèi)容編碼技術(shù)卻是普遍被使用的。考慮到這種技術(shù)會(huì)給大型的網(wǎng) 站們帶來帶寬上的極大節(jié)省,用于突破傳統(tǒng)的系統(tǒng)管理員都會(huì)積極探索并家以使用HTTP壓縮技術(shù)。
我們可以在瀏覽器發(fā)出的Accept
請(qǐng)求的頭部看到HTTP內(nèi)容編碼的鍵值。我們來看看Mozilla Firefox瀏覽器的這個(gè)請(qǐng)求,如下,我們特別注意一下Accept
,Accept-Language
,Accept-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
這些個(gè)"Accept"
值
會(huì)被服務(wù)器用到,進(jìn)而決定將適當(dāng)?shù)膬?nèi)容通過內(nèi)容協(xié)商(Content
Negotiation)發(fā)回來—這是非常有用的功能,它可以讓網(wǎng)站服務(wù)器返回不同的語言、字符集、甚至還可以根據(jù)使用者的習(xí)慣返回不同的技術(shù)。關(guān)于內(nèi)容
協(xié)商的討論很多,我們這就不再多講。我們主要來看看和服務(wù)器端壓縮有關(guān)的一些東西。Accept-Encoding
表明了瀏覽器可接受的除了純文本之外的內(nèi)容編碼的類型,比如gzip壓縮還是deflate壓縮內(nèi)容。
我們下面來看看IE發(fā)出的請(qǐng)求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
假設(shè)當(dāng)今主流的每種瀏覽器都支持gzip和deflate編碼(那些不支持的也不會(huì)發(fā)出Accept-Encoding
),我們可以簡(jiǎn)單的修改一下網(wǎng)站服務(wù)器,從而返回壓縮內(nèi)容到這些瀏覽器上,并返回標(biāo)準(zhǔn)(也就是沒有壓縮的)內(nèi)容到其他的瀏覽器上。在下例中,如果我們的瀏覽器告訴Google它不接受內(nèi)容編碼,我們會(huì)取回3,358字節(jié)的數(shù)據(jù);如果我們發(fā)出Accept-Encoding
,再加上應(yīng)答header告訴我們Content-Encoding: gzip
,我們則會(huì)取回僅僅1,213字節(jié) 。用瀏覽器的查看源代碼功能來看源代碼,我們看不出什么差異,但如果使用網(wǎng)絡(luò)跟蹤的話,我們就會(huì)發(fā)現(xiàn)其響應(yīng)是不同的。
圖一: Google壓縮 / 非壓縮對(duì)比
上例中,雖然文件不大,但是效果依然很明顯—壓縮后比原來小了74%。再加上我們前面兩部分談到的HTML、CSS、和JavaScript代碼優(yōu)化,Google在提升網(wǎng)站性能上的成果非常驚人—它的一個(gè)網(wǎng)頁居然可以放在一個(gè)TCP響應(yīng)包里。
雖 然Google在帶寬上的考慮也遠(yuǎn)遠(yuǎn)超出其他一般的網(wǎng)站,HTTP內(nèi)容編碼進(jìn)一步讓HTML、CSS、和JavaScript等瘦身50%甚至更多。不好 的地方是,HTTP內(nèi)容編碼(詞語‘壓縮’和‘內(nèi)容編碼’在本文中基本上是一個(gè)意思) 基本上針對(duì)文本內(nèi)容很有效,對(duì)于圖像和其他二進(jìn)制文件的壓縮效果就一般了,有時(shí)可能根本沒有效果,但總的來說,即使有很多二進(jìn)制文件的時(shí)候,整體上可以瘦 身15%到30%那么多。
HTTP內(nèi)容編碼的服務(wù)器端支持
如果你現(xiàn)在認(rèn)同HTTP壓縮的 價(jià)值,下一個(gè)大問題是:你如何來實(shí)施?在Apache網(wǎng)站服務(wù)器上,可以使用mod_deflate來進(jìn)行HTTP內(nèi)容的編碼。在微軟的IIS上,就有些 麻煩了。雖然IIS 5可以支持gzip的編碼壓縮,但實(shí)施起來還是超級(jí)麻煩,尤其考慮到因?yàn)楦鞣N瀏覽器中細(xì)微差異來進(jìn)行各種細(xì)致參數(shù)調(diào)整的時(shí)候。所以在IIS 5上,還是要考慮第三方的采用ISAPI過濾器的壓縮插件,比如httpZip 就是最好的一種。IIS 6上集成了壓縮功能,也更快更靈活,但是還是配置起來比較復(fù)雜。ZipEnable 帶給我們第一個(gè)專為IIS 6集成壓縮細(xì)致管理的工具—并且還有瀏覽器兼容情況監(jiān)測(cè)功能。
服務(wù)器內(nèi)容編碼的實(shí)質(zhì)
當(dāng) 實(shí)施HTTP壓縮時(shí),要平衡考慮一些因素;如果將服務(wù)器配置成‘輸出’的內(nèi)容壓縮方式,雖然可以降低帶寬的使用,但同時(shí)卻增加了CPU的開銷。多數(shù)情況 下,這不是什么大問題,尤其當(dāng)網(wǎng)站服務(wù)器所作工作很少的時(shí)候。不過,在網(wǎng)絡(luò)瀏覽很繁重的網(wǎng)站服務(wù)器上,運(yùn)行相當(dāng)多的動(dòng)態(tài)內(nèi)容就可能會(huì)達(dá)到CPU工作的極 限,這時(shí)再進(jìn)而進(jìn)行壓縮的話,CPU可能會(huì)超負(fù)荷運(yùn)行了。通過添加而外的服務(wù)器硬件資源,當(dāng)然可能會(huì)減輕這種問題,并讓我們享受通過壓縮而節(jié)省下來的帶 寬, 但最后帶寬和CPU的問題還是要看哪個(gè)成本更高。
說到底,系統(tǒng)管理員和網(wǎng)站開發(fā)者是否對(duì)HTTP的壓縮有興趣,還是要看最 后的效果如何。當(dāng)我們明顯的發(fā)現(xiàn)帶寬的負(fù)載下來了,那么訪問者也可能會(huì)明顯感覺轉(zhuǎn)載網(wǎng)頁的速度慢了。因?yàn)椋瑝嚎s產(chǎn)生和解壓縮會(huì)帶來的CPU負(fù)載, TTFB (time to first byte)也通常會(huì)增加,這樣瀏覽器渲染網(wǎng)頁的速度也會(huì)降下來,但這還算是很好的平衡,因?yàn)閿?shù)據(jù)壓縮后傳輸?shù)陌冃×恕⒆兩倭耍峤坏乃俣葧?huì)變快,這個(gè)快 速回補(bǔ)償網(wǎng)頁渲染的慢速。然而,對(duì)于寬帶用戶來說,這樣的改善可能就不明顯了。不過,這兩種情況下,對(duì)于網(wǎng)站建設(shè)者來說,都可以節(jié)省一些網(wǎng)絡(luò)上的投資。當(dāng) 然,如果可感知的反應(yīng)時(shí)間對(duì)某網(wǎng)站來說是主要目標(biāo),并且網(wǎng)站的訪問者很多都還使用撥號(hào)上網(wǎng),那么本文的第二部分鐘所講的緩沖控制就是比較好的性能提高策 略。
最后,HTTP內(nèi)容編碼的另一個(gè)潛在問題是和由腳本產(chǎn)生的網(wǎng)頁帶來的服務(wù)器負(fù)載有關(guān)的,比如PHP和ASP。在此種情況下, 主要的問題是,網(wǎng)頁內(nèi)容每次請(qǐng)求可能會(huì)被再壓縮,這樣就會(huì)給服務(wù)器增加更多的負(fù)載(相對(duì)壓縮靜態(tài)內(nèi)容來說)。如果,網(wǎng)站中所有的網(wǎng)頁都是在請(qǐng)求時(shí)生成的 話,那么使用HTTP內(nèi)容編碼就得格外小心了。還好,很多商業(yè)上使用的壓縮插件,直到如何對(duì)內(nèi)容進(jìn)行緩沖,但業(yè)余(較便宜的)的壓縮工具可能就沒有這些特 性了。
動(dòng)態(tài)網(wǎng)頁:立即生成,還是稍后生成?
有趣的是,很多的開發(fā)者都是在網(wǎng)站被訪問時(shí)開 始動(dòng)態(tài)的生成很多甚至全部他們網(wǎng)站的網(wǎng)頁。比如,http://www.domain.com/article.php?id=5就是一個(gè)通用的URL, 它暗示了某個(gè)網(wǎng)頁是由數(shù)據(jù)庫查詢時(shí)或填充模版生成的。這種常用方法的問題是,在很多情況下,在請(qǐng)求時(shí)間生成一個(gè)網(wǎng)頁是pointless的,因?yàn)楹芏鄷r(shí)候 這個(gè)主要的靜態(tài)的(所謂的靜態(tài)的動(dòng)態(tài)網(wǎng)頁、或腳本網(wǎng)頁),其內(nèi)容很長(zhǎng)時(shí)間也不變化,這顯然對(duì)于提高網(wǎng)頁裝載速度沒有什么幫助。實(shí)際上,在一個(gè)高負(fù)荷的網(wǎng)站 這種方式會(huì)嚴(yán)重的降低服務(wù)期的性能。
要避免不必要的動(dòng)態(tài)網(wǎng)頁的生成,有一個(gè)方法是,每次有變化時(shí),則預(yù)先生成有內(nèi)容的靜態(tài). html網(wǎng)頁。如果這些生成的.html網(wǎng)頁,還是經(jīng)過了代碼優(yōu)化(在本文第一部分中過這些描述方法),則更好。這不僅會(huì)讓服務(wù)器交付這些網(wǎng)頁更快變得更 容易,而且這些技術(shù)還會(huì)使搜索引擎更友好。
不幸的是,在很多情況下,簡(jiǎn)單的生成動(dòng)態(tài)的HTML網(wǎng)頁并不太容易,也為很多網(wǎng)頁只有 在網(wǎng)頁被訪問時(shí)才能夠正確的生成動(dòng)態(tài)內(nèi)容。在這種情況下,你最好是對(duì)網(wǎng)頁進(jìn)行‘烘焙’生成快速執(zhí)行的形式。在ASP .NET的情況下,這種形式則是二進(jìn)制代碼,在服務(wù)器端執(zhí)行的特別快。不好的地方是,在用戶訪問之前,服務(wù)器需要先執(zhí)行這些網(wǎng)頁強(qiáng)制執(zhí)行這些字節(jié)代碼。還 好,在ASP .NET 2.0中,這些問題將得到改善。在PHP中,一些諸如Zend等的優(yōu)化軟件是不錯(cuò)的投資。
對(duì)于提交靜態(tài) 和動(dòng)態(tài)網(wǎng)頁、或者HTML和圖像的不同需要來說,考慮一下針對(duì)物理服務(wù)器或其他的硬件上的加速可能,也是比較明智的選擇。為了網(wǎng)頁加速而加強(qiáng)硬件方面的投 入的另一個(gè)方法是專業(yè)化—不同的部件進(jìn)行不同的工作,這樣產(chǎn)生出最大的效率。雖然,本文是從代碼和網(wǎng)站服務(wù)器校對(duì)來說明如何提高網(wǎng)站的性能的,我們也不妨 討論討論其他相關(guān)的元素。
對(duì)網(wǎng)站服務(wù)器進(jìn)行渦輪增壓
加速網(wǎng)站要考慮的一個(gè)重點(diǎn)是服務(wù)器軟 件和服務(wù)器硬件。先談軟件,網(wǎng)站系統(tǒng)管理員不太可能來回因?yàn)橐子眯詥栴}、性能問題、安全問題等在Apache和IIS之間切換來切換去。簡(jiǎn)言之,網(wǎng)站服務(wù) 器和其底層的操作系統(tǒng)之間的關(guān)系錯(cuò)綜復(fù)雜、互相影響,再進(jìn)行系統(tǒng)或服務(wù)遷移則更是繁重且有風(fēng)險(xiǎn)的工作。所以,你如果真的考慮放棄一種網(wǎng)站服務(wù)器而使用另一 種的話,你必須嚴(yán)肅認(rèn)真的好好考慮這個(gè)問題;而如果速度是考慮的第一要素的話,建議你考慮一下Zeus。
再談?dòng)布绻紤]升 級(jí)硬件,則先仔細(xì)分析一下服務(wù)器上的主要任務(wù)。在靜態(tài)網(wǎng)站上,主要的工作是調(diào)整網(wǎng)絡(luò)連接和把文件從磁盤拷貝到網(wǎng)絡(luò)上。要加速這樣類型的網(wǎng)站,你得把注意力 放在高速硬盤子系統(tǒng)和高速網(wǎng)絡(luò)子系統(tǒng)上,另外還得有足夠多的內(nèi)存來處理并發(fā)請(qǐng)求。實(shí)際上,你可能得給服務(wù)器添加大量的內(nèi)存,從而為經(jīng)常使用的對(duì)象盡可能的 增加內(nèi)存緩沖來減輕磁盤的存取。有趣的是,CPU的速度在這里卻不是十分關(guān)鍵。雖然不能否認(rèn)CPU對(duì)網(wǎng)站的整體性能有影響,但瓶頸主要發(fā)生在磁盤上。但 是,當(dāng)網(wǎng)站處理動(dòng)態(tài)網(wǎng)頁和靜態(tài)網(wǎng)頁差不多一樣多的時(shí)候,處理器就顯得很關(guān)鍵了,但即便如此高速磁盤或雙網(wǎng)卡還是更有效一些。另一種情況下,除了要處理動(dòng)態(tài) 網(wǎng)頁,還要處理其他占用CPU的操作(比如SSL和HTTP壓縮等)的時(shí)候,CPU就顯得十分關(guān)鍵了。換句話說,要加速網(wǎng)站服務(wù)時(shí),服務(wù)器具體所作的工作 決定著什么類型的硬件資源更需要增強(qiáng)。
當(dāng)你沒有那么多增加服務(wù)器硬件或軟件的預(yù)算時(shí),還有一些物美價(jià)廉的解決方法。比如,你可以 對(duì)服務(wù)器的TCP/IP設(shè)置進(jìn)行優(yōu)化,這樣依賴TCP/IP網(wǎng)絡(luò)的HTTP便可以最優(yōu)運(yùn)行。TCP/IP的設(shè)置優(yōu)化里,有一項(xiàng)是TCP的接受窗口,可以把 它調(diào)整成最適合應(yīng)用或者最適合網(wǎng)絡(luò)連接的,或者是針對(duì)確保TCP連接的一些參數(shù)(如ACK或TCP_NODELAY等)進(jìn)行調(diào)整,根據(jù)具體情況設(shè)置成使用 或不使用。還有一些參數(shù),比如TIME_WAIT時(shí)間等,也是可以進(jìn)行調(diào)整的。但要記住,不管怎么調(diào)整這些網(wǎng)站服務(wù)或操作系統(tǒng)的參數(shù),都必須進(jìn)行真實(shí)的加 載試驗(yàn)以驗(yàn)證你的調(diào)整會(huì)不會(huì)反而減慢用戶訪問的服務(wù)或帶來新的問題。此外,一定要弄懂這些參數(shù)之后,再進(jìn)行調(diào)整。
通過分工進(jìn)行加速
網(wǎng)站加速還可以考慮的一個(gè)出發(fā)點(diǎn)是,不同的網(wǎng)站內(nèi)容可能會(huì)擁有不同的提交特性。考慮到不同的內(nèi)容,其特性也不同,我們可以用多個(gè)服務(wù)器,每個(gè)服務(wù)器來執(zhí)行不同的內(nèi)容處理,這樣可能比用服務(wù)器池(server farm)中的每一個(gè)服務(wù)來處理同樣的任務(wù)要好得多。
我 們來看一個(gè)分工進(jìn)行加速的簡(jiǎn)單例子。當(dāng)你的商務(wù)網(wǎng)站給購(gòu)物車或外部網(wǎng)使用SSL加密的時(shí)候,你會(huì)發(fā)現(xiàn)當(dāng)有多個(gè)用戶同時(shí)訪問的時(shí)候,SSL加密帶來 HTTPS段的明顯負(fù)載會(huì)使你的服務(wù)器的性能會(huì)急劇下降。這種情況下,把流量分配給另一臺(tái)服務(wù)器,其意義就十分明顯了。比如,把你的主站點(diǎn)放在 www.domain.com上,把結(jié)賬的處理部分放在shop.domain.com上。這個(gè)shop.domain.com就是一個(gè)專門處理SSL流 量的服務(wù)器,可能會(huì)用到SSL加速卡。采取分工的方式,可以讓你專心處理結(jié)賬的用戶的SSL流量,而不至于像以往SSL的處理會(huì)導(dǎo)致服務(wù)器整體性能的下 降。對(duì)于圖像和其他重量級(jí)的二進(jìn)制的比如PDF文檔或.exe文檔,服務(wù)器處理其下載可能要花些力氣,這些連接通常持續(xù)的時(shí)間比一般的連接都長(zhǎng),會(huì)消耗大 量寶貴的TCP/IP資源。進(jìn)而,對(duì)于這些媒體資源(PDF、.exe、圖像等)的處理,我們也并不需要把它們和文本資源(HTML、CSS和 JavaScript等)等同對(duì)待處理。在這種情況下,讓處理文本資源的服務(wù)器有高性能的CPU,讓處理媒體資源的服務(wù)器有大帶寬,是有的放矢的解決之 道。
分工還可以進(jìn)一步應(yīng)用到網(wǎng)頁的生成上。我們可以考慮把生成網(wǎng)頁的工作單獨(dú)放在一個(gè)服務(wù)器上,把處理靜態(tài)內(nèi)容的工作放在另一個(gè) 服務(wù)器上。現(xiàn)在已然有很多網(wǎng)站是采取這樣的模式了,這其中很多網(wǎng)站會(huì)使用一個(gè)叫做Squid的反向代理(reverse proxy)。在設(shè)置過程中,代理服務(wù)器專門提供靜態(tài)的內(nèi)容,速度很快;而后臺(tái)的服務(wù)器則可以專心處理在訪問時(shí)才會(huì)產(chǎn)生的動(dòng)態(tài)內(nèi)容。緩沖控制策略和規(guī)則, 我們?cè)诘诙糠种姓劦竭^,在這時(shí)的設(shè)置過程中就顯得十分重要了;我們得確保代理服務(wù)器的緩沖中儲(chǔ)存的內(nèi)容在共享緩沖中是安全的。
為了爭(zhēng)奪市場(chǎng)而提速
我 們剛才談的那些東西主要是一些低成本的加速技術(shù),在我們本文即將結(jié)束的時(shí)候,我們來看看一些需要軟硬件成本很高但收益可觀的方法。目前市場(chǎng)上提供有一些需 要花些錢的獨(dú)特加速設(shè)備,它們可以進(jìn)行比如網(wǎng)絡(luò)連接分流、壓縮、緩沖、和其他等技術(shù),從而達(dá)到加速的目的。 如果你不在乎投資高帶寬的話,這些解決方案就十分有效,但是大多數(shù)的網(wǎng)站還是更喜歡我們先前介紹過的物美價(jià)廉的方法,比如代碼優(yōu)化、緩沖、和HTTP編碼 等。
就算你有很多資金,可以投資一個(gè)服務(wù)器池(server farm)、并添加最高檔的加速設(shè)備,也使用壓縮和緩沖技術(shù)等,但你還是會(huì)最后達(dá)到一個(gè)極限。要想進(jìn)一步再提速,還有最后一招:把內(nèi)容放在離訪問者最近的 地方,有可能的話,在那個(gè)地方再實(shí)施上述各類技術(shù)(如壓縮、緩沖等)。你肯定注意過,有些網(wǎng)站提供鏡像服務(wù)器等,這樣世界各地的訪問者就可以就近訪問所需 內(nèi)容。不過,還有比這個(gè)更有地理分布意義的方法,并且可以透明的讓訪問者使用。內(nèi)容分發(fā)網(wǎng)絡(luò)(Content Distribution Network – CDN),比如Akamai,就可以讓我們把重型內(nèi)容(如圖象和其他二進(jìn)制內(nèi)容等)搬移到離訪問者更近的地方,這樣通過內(nèi)容分發(fā)網(wǎng)站在世界各地的邊緣緩 沖,訪問者訪問起來就會(huì)更快。這種方式帶來了性能上極大提高,目前世界級(jí)的一些大網(wǎng)站都在使用。雖然這算不上是經(jīng)濟(jì)實(shí)用的方法,但作為這些方法的最后補(bǔ) 充,放在這里以饗讀者。
Thomas A. Powell 是PINT公司的創(chuàng)始人,也是加州大學(xué)San Diego分校計(jì)算機(jī)科學(xué)系的講師,以及一些網(wǎng)頁開發(fā)書籍的作者,其所著書目包括《HTML & XHTML: The Complete Reference》和 《JavaScript: The Complete Reference》等。Joe Lima 是Port80軟件公司的首席構(gòu)架師(architect),同時(shí)教授UCSD 擴(kuò)展的服務(wù)器技術(shù)。
Port80軟件公司
Port80 Software, Inc. 是微軟 Internet Information Services (IIS) 網(wǎng)絡(luò)服務(wù)的領(lǐng)先的開發(fā)商. 公司同時(shí)提供w3compiler, 一套優(yōu)化代碼的桌面應(yīng)用軟件。Port80 Software 是微軟認(rèn)證合作商(MCP ISV)。它位于San Diego, CA. 更多信息請(qǐng)見公司網(wǎng)站 www.port80software.com.