1. 程式人生 > >Web伺服器處理HTTP壓縮之gzip、deflate壓縮

Web伺服器處理HTTP壓縮之gzip、deflate壓縮

一、什麼是gzip

        gzip是一種資料格式,預設且目前僅使用deflate演算法壓縮data部分;

        Gzip是一種流行的檔案壓縮演算法,現在的應用十分廣泛,尤其是在Linux平臺。當應用Gzip壓縮到一個純文字檔案時,效果是非常明顯的,大約可以減少70%以上的檔案大小。這取決於檔案中的內容。

      利用Apache中的Gzip模組,我們可以使用Gzip壓縮演算法來對Apache伺服器釋出的網頁內容進行壓縮後再傳輸到客戶端瀏覽器。這樣經過壓縮後實際上降低了網路傳輸的位元組數,最明顯的好處就是可以加快網頁載入的速度。

      網頁載入速度加快的好處不言而喻,除了節省流量,改善使用者的瀏覽體驗外,另一個潛在的好處是Gzip與搜尋引擎的抓取工具有著更好的關係。例如 Google就可以通過直接讀取gzip檔案來比普通手工抓取更快地檢索網頁。在Google網站管理員工具(Google Webmaster Tools)中你可以看到,sitemap.xml.gz 是直接作為Sitemap被提交的。

      而這些好處並不僅僅限於靜態內容,PHP動態頁面和其他動態生成的內容均可以通過使用Apache壓縮模組壓縮,加上其他的效能調整機制和相應的伺服器端 快取規則,這可以大大提高網站的效能。因此,對於部署在Linux伺服器上的PHP程式,在伺服器支援的情況下,我們建議你開啟使用Gzip Web壓縮。

二、什麼是deflate

        DEFLATE是同時使用了LZ77演算法與哈夫曼編碼(Huffman Coding)的一個無損資料壓縮演算法。

        它最初是由Phil Katz為他的PKZIP歸檔工具第二版所定義的,後來定義在RFC 1951規範中。

        人們普遍認為DEFLATE不受任何專利所制約,並且在LZW(GIF檔案格式使用)相關的專利失效之前,這種格式除了在ZIP檔案格式中得到應用之外也在gzip壓縮檔案以及PNG影象檔案中得到了應用。

        DEFLATE壓縮與解壓的原始碼可以在自由、通用的壓縮庫zlib上找到。

        更高壓縮率的DEFLATE是7-zip所實現的。AdvanceCOMP也使用這種實現,它可以對gzip、PNG、MNG以及ZIP檔案進行壓縮從而得到比zlib更小的檔案大小。在Ken Silverman的KZIP與PNGOUT中使用了一種更加高效同時要求更多使用者輸入的DEFLATE程式。

deflate是一種壓縮演算法,是huffman編碼的一種加強。

        deflate與gzip解壓的程式碼幾乎相同,可以合成一塊程式碼。

三、web伺服器處理http壓縮的過程

    1. Web伺服器接收到瀏覽器的HTTP請求後,檢查瀏覽器是否支援HTTP壓縮(Accept-Encoding 資訊);

    2. 如果瀏覽器支援HTTP壓縮,Web伺服器檢查請求檔案的字尾名;

    3. 如果請求檔案是HTML、CSS等靜態檔案,Web伺服器到壓縮緩衝目錄中檢查是否已經存在請求檔案的最新壓縮檔案;

    4. 如果請求檔案的壓縮檔案不存在,Web伺服器向瀏覽器返回未壓縮的請求檔案,並在壓縮緩衝目錄中存放請求檔案的壓縮檔案;

    5. 如果請求檔案的最新壓縮檔案已經存在,則直接返回請求檔案的壓縮檔案;

    6. 如果請求檔案是動態檔案,Web伺服器動態壓縮內容並返回瀏覽器,壓縮內容不存放到壓縮快取目錄中。

下面是兩個演示圖:

未使用Gzip:

開啟使用Gzip後:

四、gzip與deflate區別

        deflate使用inflateInit(),而gzip使用inflateInit2()進行初始化,比 inflateInit()多一個引數: -MAX_WBITS,表示處理raw deflate資料。因為gzip資料中的zlib壓縮資料塊沒有zlib header的兩個位元組。使用inflateInit2時要求zlib庫忽略zlib header。在zlib手冊中要求windowBits為8..15,但是實際上其它範圍的資料有特殊作用,見zlib.h中的註釋,如負數表示raw deflate。        

        Apache的deflate變種可能也沒有zlib header,需要新增假頭後處理。即MS的錯誤deflate (raw deflate).zlib頭第1位元組一般是0x78, 第2位元組與第一位元組合起來的雙位元組應能被31整除,詳見rfc1950。例如Firefox的zlib假頭為0x7801,python zlib.compress()結果頭部為0x789c。        

        deflate 是最基礎的演算法,gzip 在 deflate 的 raw data 前增加了 10 個位元組的 gzheader,尾部添加了 8 個位元組的校驗位元組(可選 crc32 和 adler32) 和長度標識位元組。

        安裝它們的Apache Web伺服器版本的差異。Apache 1.x系列沒有內建網頁壓縮技術,所以才去用額外的第三方mod_gzip 模組來執行壓縮。而Apache 2.x官方在開發的時候,就把網頁壓縮考慮進去,內建了mod_deflate 這個模組,用以取代mod_gzip。雖然兩者都是使用的Gzip壓縮演算法,它們的運作原理是類似的。     

        壓縮質量。mod_deflate 壓縮速度略快而mod_gzip 的壓縮比略高。一般預設情況下,mod_gzip 會比mod_deflate 多出4%~6%的壓縮量。

        對伺服器資源的佔用。 一般來說mod_gzip 對伺服器CPU的佔用要高一些。mod_deflate 是專門為確保伺服器的效能而使用的一個壓縮模組,mod_deflate 需要較少的資源來壓縮檔案。這意味著在高流量的伺服器,使用mod_deflate 可能會比mod_gzip 載入速度更快。即在伺服器效能足夠的情況下,使用mod_gzip,雖然會耗費伺服器效能,但是值得(壓縮更快更好);在伺服器效能不足的情況下,使用mod_deflate 確保效能。

        從Apache 2.0.45開始,mod_deflate 可使用DeflateCompressionLevel 指令來設定壓縮級別。該指令的值可為1(壓縮速度最快,最低的壓縮質量)至9(最慢的壓縮速度,壓縮率最高)之間的整數,其預設值為6(壓縮速度和壓縮質 量較為平衡的值)。這個簡單的變化更是使得mod_deflate 可以輕鬆媲美mod_gzip 的壓縮。

五、開啟mod_gzip、mod_deflate

        Apache上利用Gzip壓縮演算法進行壓縮的模組有兩種:mod_gzip 和mod_deflate。 要使用Gzip Web壓縮,請首先確定你的伺服器開啟了對這兩個元件之一的支援。在Linux伺服器上,現在已經有越來越多的空間商開放了對它們的支援,有的甚至是同時 支援這兩個模組的。例如目前Godaddy、Bluehost及DreamHosts等空間商的伺服器都已同時支援mod_gzip 和mod_deflate。        

        通過檢視HTTP頭,我們可以快速判斷使用的客戶端瀏覽器是否支援接受gzip壓縮。若傳送的HTTP頭中出現以下資訊,則表明你的瀏覽器支援接受相應的gzip壓縮:

    Accept-Encoding: gzip 支援mod_gzip
    Accept-Encoding: deflate 支援mod_deflate 
    Accept-Encoding: gzip,deflate 同時支援mod_gzip 和mod_deflate

        mod_deflate 是apache自帶的模組,當然是在apache 2後支援的,以前1的時候是mod_gzip,啟用mod_deflate可以很好的為節省網頁大小,只不過是佔用伺服器的資源和記憶體.使用者看到頁面的速度會大大加快。在apache2.0以上(包括apache2.0)的版中gzip壓縮使用的是mod_deflate模組

1. 檢視apache的安裝模式
apachectl -l

發現 mod_so.c,ok可以動態加模組,不用重新編譯。

2. 安裝mod_deflate
找到原有的apache安裝包安裝mod_deflate
cd httpd-2.0.59/modules/filters
/usr/local/apache2/bin/apxs -i -c -a mod_deflate.c

PS:apxs命令引數說明:
        -i  此選項表示需要執行安裝操作,以安裝一個或多個動態共享物件到伺服器的modules目錄中。
        -a  此選項自動增加一個LoadModule行到httpd.conf檔案中,以啟用此模組,或者,如果此行已經存在,則啟用之。
        -A  與 -a 選項類似,但是它增加的LoadModule命令有一個井號字首(#),即此模組已經準備就緒但尚未啟用。
        -c  此選項表示需要執行編譯操作。它首先會編譯C源程式(.c)files為對應的目的碼檔案(.o),然後連線這些目的碼和files中其餘的目的碼檔案(.o和.a),以生成動態共享物件dsofile 。如果沒有指定 -o 選項,則此輸出檔名由files中的第一個檔名推測得到,也就是預設為mod_name.so 。

3、修改Apache的http.conf檔案,去除mod_deflate.so前面的註釋

LoadModule deflate_module modules/mod_deflate.so

4、在根目錄中新建.htaccess檔案,定製壓縮規則

#GZIP壓縮模組配置<ifmodule mod_deflate.c>
#啟用對特定MIME型別內容的壓縮
SetOutputFilter DEFLATESetEnvIfNoCase Request_URI .(?:gif|jpe?g|png|exe|t?gz|zip|bz2|sit|rar|pdf|mov|avi|mp3|mp4|rm)$ no-gzip dont-vary #設定不對壓縮的檔案AddOutputFilterByType DEFLATE text/html text/css text/plain text/xml application/x-httpd-php application/x-javascript #設定對壓縮的檔案</ifmodule>

5、對指定的檔案配置快取的生存時間,去除mod_headers.so模組前面的註釋

LoadModule headers_module modules/mod_headers.so

6、在根目錄中新建.htaccess檔案,定製壓縮規則

#檔案快取時間配置
<FilesMatch ".(flv|gif|jpg|jpeg|png|ico|swf|js|css)$">
Header set Cache-Control "max-age=2592000"
</FilesMatch>

裡面的檔案MIME型別可以根據自己情況新增,至於PDF 、圖片、音樂文件之類的這些本身都已經高度壓縮格式,重複壓縮的作用不大,反而可能會因為增加CPU的處理時間及瀏覽器的渲染問題而降低效能。所以就沒必要再通過Gzip壓縮。通過以上設定後再檢視返回的HTTP頭,出現以下資訊則表明返回的資料已經過壓縮。即網站程式所配置的Gzip壓縮已生效。

Content-Encoding: gzip

注:不管使用mod_gzip 還是mod_deflate,此處返回的資訊都一樣。因為它們都是實現的gzip壓縮方式。

遇到的問題以及解決:

1:

apach2 安裝mod_deflate後restart,直接

load /opt/apache/modules/mod_deflate.so into server: /opt/apache/modules/mod_deflate.so: undefined symbol: deflate 異常的痛苦

什麼ldd mod_deflate.so後再export LIB_LIBRARY_PATH呀,都試了N次,google也go了N天

終於在google上go出來一篇文章,終於解決,方法如下: vi /usr/local/apache2/bin/apr-config 修改LDFLAGS=" " 為 LDFLAGS="-lz" 然後再apxs -ica mod_deflate.c 就OK了.

2:
apach2 安裝mod_deflate後restart,直接

module deflate_module is built-in and can't be loaded ...

這說明該模組已經安裝,不必再LoadModule deflate_module啟用它。

只需做<ifmodule mod_deflate.c>配置

參考: