Nginx學習:壓縮模塊Gzip又是一個非常常見的模塊,Gzip 現在也是事實上的 Web 應用壓縮標準了。隨便打開一個網站,在請求的響應頭中都會看到 具體的壓縮算法咱們就不多說了,反正文字類的,相同字符越多的壓縮效果越好。這也是大部分壓縮算法的特點。其它的,咱們就直接看配置吧。 今天學習的內容都是可以設置在 http、server、location 中的,有特殊情況的我會單獨說。 GzipGzip 模塊的全稱是 ngx_http_gzip_module ,是包含在 Nginx 源碼中的,不需要再獨立的編譯。它是一個使用 “gzip” 壓縮算法壓縮響應的過濾器,通常有助于將傳輸數據的大小減少一半甚至更多。需要注意的是,使用 SSL/TLS 協(xié)議時,壓縮響應可能會受到 BREACH 攻擊。我們先來看 Gzip 配置指令,然后下一小節(jié)再看一個綜合測試。 gzip啟用或禁用響應的 Gzip 壓縮功能。
默認是 off 的,在 nginx.conf.default 中是有它的注釋的。一般來說,我們會在一個服務器上直接在 http 模塊中配置全部的站點是否都開啟 Gzip ,當然,也有可能會針對某個站點單獨在對應的 server 中開啟。而在 location 中,往往是讓某些路徑或文件資源不開啟 Gzip 。這是為啥呢? 要知道,壓縮是 CPU 密集型的操作,要耗費 CPU 資源的。特別是對于特別大的文件和特別高的壓縮率。因此,圖片和視頻或者非常大的文件其實并不是很適合去進行 Gzip 壓縮的,并且 Gzip 壓縮還會加上自己的壓縮頭,反而會讓這類文件變得更大,比如說 JPG 文件。這種文件本來就是通過圖形壓縮算法壓縮過的,再上一道 Gzip 其實意義不大,而且很可能還會變得比原來更大。 因此,最合適壓縮的,還是普通的文本類型的響應,比如純文本文件、html/css/js響應、xml、JSON數據等等。 gzip_buffers設置用于壓縮響應的緩沖區(qū)的數量和大小。
默認情況下,緩沖區(qū)大小等于一內存頁。這是 4K 或 8K,具體取決于平臺。 gzip_comp_level設置響應的 gzip 壓縮級別。
默認值是 1 ,可接受的值在 1 到 9 的范圍內。數值越大,壓縮比率越高,文件越小,但 CPU 耗費資源也越高。小數值就是反過來的。通常來說,要么不配置用 1 ,要么 3、4、5 左右即可。 和壓縮比率對應的還有一個變量 gzip_disable禁用對具有匹配任何指定正則表達式的“User-Agent”標頭字段的請求的響應的 gzip 壓縮。
特殊掩碼“msie6” (0.7.12) 對應于正則表達式“MSIE [4-6].”,但運行速度更快。從 0.8.11 版開始,“MSIE 6.0; ... SV1”不包含在此掩碼中。 其實就是針對指定的匹配到的 User-Agent 中的瀏覽器關鍵字段,不啟用 Gzip 壓縮。 gzip_http_version設置壓縮響應所需的請求的最低 HTTP 版本。
默認值是 1.1 ,這個基本沒啥人改了,現在 1.1 已經很普遍了。 gzip_min_length設置將被壓縮的響應的最小長度。
默認值是 20 ,就是不到這個長度的,就不壓縮了。長度僅由 “Content-Length” 響應頭字段確定。 gzip_proxied根據請求和響應啟用或禁用代理請求的響應 gzip 壓縮。
默認值是 off ,請求被代理的結果是由“Via”請求頭字段的存在決定的。該指令接受多個參數:
官方的解釋是 僅將響應壓縮到不會在代理服務器上緩存的請求是合理的,代理請求主要指的是一些高速緩存服務器或 CDN 網絡,和 gzip_vary 指令類似。通過請求的 Via 請求頭,判斷當前的請求是不被代理轉發(fā)過來的請求,如果有這個參數,那么 gzip_proxied 就會生效。 gzip_types對除了 “text/html” 之外,還啟用對指定 MIME 類型的響應的 gzip 壓縮。
特殊值 “*” 匹配任何 MIME 類型 (0.8.29)。默認值 “text/html” 類型的響應總是被壓縮的。 比如說,你想要壓縮 JSON、XML 和 JPG 類型的資源,就可以這么配。
不用再加 text/html ,默認它就一直存在,寫上了反而會報重復的錯誤。 gzip_vary如果指令 gzip、gzip_static 或 gunzip 處于活動狀態(tài),則啟用或禁用插入 “Vary: Accept-Encoding” 響應頭字段。
默認值是 off 的,Vary 是 HTTP 中響應頭的一個標識,主要是和緩存代理服務器響應有關,針對現在比較流行的一些云服務,比如高速緩存中間件或者 CDN 網絡。如果開啟的話,就會添加一個上面那樣的響應頭,告訴緩存代理服務器緩存兩種版本的資源:壓縮和非壓縮的,這有助于避免一些公共代理不能正確地檢測 Content-Encoding 標頭的問題。 假設有兩個客戶,一個使用的舊瀏覽器不支持壓縮,一個使用新的瀏覽器支持壓縮,如果他們都請求同一個網頁,那么取決于誰先請求,壓縮或非壓縮版本便存儲在CDN上。這樣問題就出現了,舊瀏覽器請求常規(guī)網頁但獲得緩存的壓縮版本,而新瀏覽器會獲得緩存的非壓縮版本但嘗試去“解壓”它。無論哪種方式都是壞消息。解決方法是,源服務器回送“Vary: Accept-Encoding”。如果你的網站使用了這些中間件或者 CDN ,記得開啟它哦。 綜合測試先來一個整體的配置,我們直接到 http 下面去配置,這樣的話所有的站點所有的目錄都可以啟用 Gzip 了,比較方便。
下面兩個注釋我們后面再說,先看看效果,配置上述內容之后,訪問所有的頁面都會在響應頭中返回 首先是關閉 Gzip 狀態(tài)下抓到的數據。 可以看到,數據是以原文展示的,說明就是返回的普通文本字符串?,F在咱們看看打開 Gzip 的效果。 好嘛,直接變亂碼了,這就說明 Gzip 確實是啟用了。如果文件內容不多,可能在瀏覽器返回的 Length 中看不到太大的差別,那么我們就可以自己寫一個大點的頁面,或者之前使用 php 循環(huán)輸出多點內容。gzip_vary 開啟后,響應頭會有 壓縮級別,這里我直接使用之前的那個循環(huán)打印10000 次 怎么樣,效果還是很明顯的吧,返回的大小直接從 14.7M 變成了最小 74.1k 。因為我們的循環(huán)內容都是一樣的,所以壓縮比率非常高。查看等級 1 在日志中記錄的 大小限制在上面的配置中,我們設置了一個 大家可以自己進行測試,直接訪問 a.txt 是不會壓縮的,修改 gzip_min_length 小于 16 之后,就會進行壓縮了。 gzip_disable 與 gzip_proxied在上面的配置中,gzip_disable 我配置的就是過濾掉 Chrome 瀏覽器,大家可以自己試試打開注釋后,Chrome 瀏覽器訪問還有沒有 Gzip 。另一個的測試也不麻煩,可以使用 Postman ,添加一個請求頭 Via ,值隨便寫,然后就會發(fā)現所有頁面或資源的 Gzip 都失效了?,F在打開注釋,Gzip 又開始生效了。注意,gzip_proxied 判斷的條件就是請求頭有沒有 Via ,至于 Via 的值是什么并不重要,咱們只是測試嘛。這個其實是針對于當前系統(tǒng)是否為被反向代理的,比如 CDN 的回源,當 CDN 回源到我們本地服務器時,或者其它 Nginx 反向代理到當前服務器時,就會加上,Via 請求頭,正常情況下 Gzip 就不會對這些請求進行壓縮處理了。gzip_proxied 就是用來控制這部分內容的,之前測試,如果在有 Via 請求頭的情況下設置為 private ,則響應內容不包含 GunZip其實一般情況下,有上面 Gzip 模塊的內容就夠用了。但是 Nginx 還提供了兩個和 Gzip 相關的拓展模塊。這兩個模塊都需要額外安裝,不是在 Nginx 源碼中的。第一個就是 ngx_http_gunzip_module 模塊,GunZip 的作用是使用“Content-Encoding: gzip”為不支持“gzip”編碼方法的客戶端解壓縮響應。當需要存儲壓縮數據以節(jié)省空間和降低 I/O 成本時,該模塊將很有用。 說人話,就是客戶端如果不支持 Gzip 壓縮,那么開啟了這個模塊功能之后,就還是會把 Gzip 的壓縮內容反解壓回去再響應給客戶端。其實現在這個模塊已經沒啥用了,畢竟基本上所有的客戶端或瀏覽器都是支持 Gzip 解壓的。但是,不排除有特殊需求吧。它是通過添加 --with-http_gunzip_module 參數在 configure 時來進行編譯安裝的,只有兩個配置項。 gunzip為缺乏 gzip 支持的客戶端啟用或禁用 gzip 響應的解壓縮。
默認值是 off ,也就是關閉的。如果啟用,則在確定客戶端是否支持 gzip 時還會考慮以下指令:gzip_http_version、gzip_proxied 和 gzip_disable。要測試的話,其實可以使用 Postman ,將請求頭中的 gunzip_buffers設置用于解壓縮響應的緩沖區(qū)的數量和大小。
默認情況下,緩沖區(qū)大小等于一內存頁。這是 4K 或 8K,具體取決于平臺。 gzip_static這個模塊從名字上來看,好像是什么靜態(tài) Gzip 的意思,其實它是允許發(fā)送帶有“.gz”文件擴展名的預壓縮文件而不是常規(guī)文件。它的命名是 ngx_http_gzip_static_module 模塊,也不是包含在 Nginx 核心源碼中的,需要通過 --with-http_gzip_static_module 編譯安裝,只有一個配置項。
默認是 off ,啟用(“on”)或禁用(“off”)檢查預壓縮文件的存在。還需要配合考慮了以下指令:gzip_http_version、gzip_proxied、gzip_disable 和 gzip_vary。 使用“always”值 (1.3.6),gzip 壓縮文件在所有情況下都使用,而不檢查客戶端是否支持它。如果磁盤上沒有未壓縮的文件或者使用了 ngx_http_gunzip_module,這將很有用。 可以使用 gzip 命令或任何其他兼容的命令來壓縮文件。建議原文件和壓縮文件的修改日期和時間一致。 網上關于這個模塊的資料很少,但通過上面官方文檔中的描述,大概可以猜測到,就是我們可以在命令行通過 gzip 命令工具或者通過其它動態(tài)程序提前壓縮好文件,和原始文件保持相同的名稱,只是后綴名變成 .gz 的。然后盡量讓它們的修改日期和時間一致。這樣如果是開啟 Gzip 的情況下,Nginx 就會直接發(fā)送 .gz 的這個預壓縮文件,而不用自己再壓縮一遍,能夠有效減少壓縮所帶來的 CPU 消耗。 那么我們就拿 a.txt 來測試一下,首先使用 gzip 壓縮一下,生成了一個 a.txt.gz 文件。
不加任何參數的話,原來的 a.txt 直接就被打包成了 a.txt.gz 文件,原始文件也不存在了。然后編譯安裝 ngx_http_gzip_static_module 模塊,之后也在 http 模塊下設置 接下來,我們再創(chuàng)建一個 a.txt 文件,讓文件的內容與之前的文件略有不同。然后在請求的時候加上 Via 頭,這樣請求就不會走 gzip 了。這樣就可以測試出在沒有 Via 頭的情況下,使用 gzip_static 確實直接就是使用 a.txt.gz 文件,而使用了 Via 就會看到原始的 a.txt 文件了。大家一定要自己測試一下哦。 總結關于 Gzip 的內容相信大家還是比較好懂的,因為接觸過這個的同學可能非常多。不管你是做網站開發(fā)還是寫接口,減少帶寬流量,優(yōu)化加載速度,通過 Gzip 都是非常方便的。其實大家應該看出來了,大部分情況下,其實我們只需要配置 另外需要注意就是對于圖片、流媒體這些,建議不要用,不過大家還是要自己試試,有的時候確實有效,有的時候真的會變得更大,這個東西吧,自己不試試是不知道的。另外順便提一個靜態(tài)資源的優(yōu)化點,圖片資源盡量使用 JPG ,因為它本身就是壓縮類型的,同樣的圖片會比 PNG 或 GIF 要小。 參考文檔: http:///en/docs/http/ngx_http_gzip_module.html http:///en/docs/http/ngx_http_gunzip_module.html http:///en/docs/http/ngx_http_gzip_static_module.html |
|