GZIP壓縮原理分析(09)——第四章 基於gzip的HTTP壓縮詳解(四03) 處理細節(關於流壓縮的問題)以及本章總結

我們構建負載均衡設備的模型來描述流壓縮的問題。模型是這樣的:負載均衡設備在服務器前端,客戶端訪問服務器實際上是訪問這個負載均衡設備,由該設備將來自客戶端的請求發送給服務器並將服務器回覆的應答發送給客戶端。HTTP壓縮功能就做在這個負載均衡設備上,服務器發送給負載均衡設備的HTTP應答是未經過壓縮的明文。由負載均衡設備將明文應答壓縮後再將壓縮結果發送給客戶端。

 

負載均衡設備在壓縮明文應答數據時有這樣兩種處理方法:

1、收齊全部明文應答數據,並且這些數據是保存在負載均衡設備內存中的。當確認全部收齊後,將這些數據統一壓縮,並將壓縮結果發送回客戶端;

2、收到部分應答數據就開始壓縮,並將這部分壓縮結果發送給客戶端,而不是非要等到收齊全部數據再壓縮(簡言之,就是收點壓點再收點再壓點。再往細講還會涉及異步或者同步壓縮,但這是涉及到負載均衡設備壓縮功能的具體實現細節方面的東西,已經不在我們這裏討論的範疇了)。

第一種方法較爲古老並且算是一種“臨時性”的方法(我最初就是用這種方法),好處是原理簡單、壓縮率較高、編碼容易、維護輕鬆,壞處是內存消耗大、擴展性差、功能較爲侷限(因爲要收齊全部應答報文,那麼爲緩存這些應答報文,使用多大的內存合適呢?如果某種情況下應答報文始終大於緩存區的尺寸,那是不是就不能提供壓縮功能了?!)。第二種方法是目前的主流,負載均衡設備業界稱之爲“流壓縮”。這種方法的好處相當明顯,不用將報文收齊就可以開始壓縮並將結果發送給客戶端,這麼做首先提高了應答報文的交付速度。其次不用緩衝全部應答報文,這樣一來對設備內存的依賴就小了,甭管需要壓縮的應答數據有多大,因爲再大也是“分組轉發”,數據是一個包一個包過來的,惹急了每一個MSS大小的數據就壓一次併發送(當然,要先讓TCP保證順序纔行)!理論上講,第二種方法是不限制待壓縮數據尺寸的,無論多大都能壓!有人會說第二種方法壓縮率不夠,其實不然,壓縮內部的實現也是分成一塊一塊的(後續講源碼的章節我會仔細分析),只要設定好與當前設備內存對應的一個應答數據收取閾值即可保證壓縮率,收取閾值大小的數據就可以開始壓縮。上文提到的那個MSS,其實就是把TCP中的那個MSS作爲這裏的“閾值”了。

 

目前不少負載均衡設備的HTTP壓縮功能都已經使用專門的硬件去實現壓縮功能了,我下面要提到的是使用軟件接口時要注意的一些實際問題,使用硬件壓縮可能並不會涉及這類問題。注意,以下這些問題都是針對流壓縮而言的。

 

對於流壓縮而言,因爲在沒有得到最終壓縮結果的時候就已經把當前的壓縮結果發送出去了,所以在發送第一個壓縮結果的時候,是不知道總壓縮結果長度的,也就是說,不能用Content-Length字段去記錄總的經過壓縮後的數據長度。但也不是絕對的,這要看那個閾值怎麼設了,要是整個應答報文都在閾值內,一次壓縮就可以搞定全部應答數據,此時當然可以使用Content-Length字段。另外,如果連接不是Keep-Alive的,那麼報文頭中可以不攜帶表示數據大小的字段,也不用chunk傳輸,使用Connection: close字段即可,直接在壓完全部數據之後斷開連接。

 

我主要想說的還是Transfer-Encoding: chunked字段。使用這個字段比較方便,每壓完一部分,把這部分放到一個chunk中即可。對於應答數據特別大的情況,使用這種傳輸方式會非常方便。但必須注意的是,每個chunk都不可以是單獨壓縮的!!!所謂單獨壓縮,就是指完成一次gzip壓縮!!!結合之前的章節,這裏的“一次”可以簡單粗暴的理解爲帶有gzip頭和尾的一次壓縮過程。也就是說,如果每個chunk裏的數據都帶有自己的gzip頭和尾,即,該chunk對應的原始數據單獨使用了一次gzip壓縮,那麼,雖然整個應答被分成了多個chunk,但是,瀏覽器,更廣義的講是客戶端,只會解壓收到的第一個chunk。雖然還有後續chunk,而且後續chunk都攜帶着自己的壓縮數據,但是瀏覽器不會解壓了!!!說到這裏,肯定有不少人會說百度等大型網站用了gzip壓縮而且還是用Transfer-Encoding傳輸的,對此,我只想說,麻煩自己抓個包一個字節一個字節的核對一下好吧!!!沒錯,這些大型網站確實是這樣做的,但是,用wireshark把收到的所有的chunk拼起來會發現,它們只有一個gzip頭和尾!!!貼圖不方便,直接看報文才直觀,用wireshark抓即可。

 

上面說的是實際現象,對於不能每個chunk就壓一次的問題,還有理論依據:

見維基百科,http://en.wikipedia.org/wiki/Chunked_transfer_encoding,如下圖所示,

可惜我沒從RFC2616中找到相應的依據,不知道是我找的不仔細還是根本沒有,只找到了下面這句話,如下圖所示,

但是沒有提到壓縮,貌似和壓縮沒有關係。無論理論依據如何,反正現網目前就是這樣的,不排除今後每個chunk可以單獨壓縮的可能(個人覺得可能性不大)。

 

本章總結

本章主要分析gzip在HTTP壓縮中的實際應用,並針對現網中的實現細節進行基本分析。這部分內容對壓縮本身來講並不是完全必要的,如果僅僅爲了瞭解壓縮,本章可以略過。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章