Nginx的Gzip功能

什麼是HTTP壓縮

有時候客戶端和服務器之間會傳輸比較大的報文數據,這時候就佔用較大的網絡帶寬和時長。爲了節省帶寬,加速報文的響應速速,能夠將傳輸的報文數據先進行壓縮,而後再進行傳輸。
HTTP支持多種報文壓縮算法,下面是一個普通的請求頭,從Accept-Encoding字段能夠看出支持gzip、deflate和br壓縮算法。本文咱們重點講使用Gzip算法對報文進行壓縮,好比Gzip來壓縮HTML,Javascript, CSS文件,壓縮完後能大大減小網絡傳輸的數據量,提升了用戶顯示網頁的速度。javascript

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: max-age=0
Connection: keep-alive
Host: localhost:8000
If-Modified-Since: Tue, 21 Apr 2020 14:09:01 GMT
If-None-Match: "5e9efe7d-264"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36

任何技術都是雙面的,HTTP壓縮雖然能減小帶寬佔用加快響應速度,可是由於須要額外的壓縮和解壓的過程,因此會佔用些客戶端或服務器端的計算資源。css

瞭解HTTP的讀者知道,能夠對HTTP的報文體進行編碼加密。其實HTTP壓縮是一種特殊的編碼方式,使用這種編碼方式能夠將報文大大減小,使用對應的解法方式又能還原最初的報文。(咱們能夠看出,其實壓縮技術的本質就是一種編碼方式)html

HTTP壓縮的使用場景

從上面對於HTTP壓縮的介紹能夠看出,這種技術是一種優化技術,經常用於壓縮服務器端返回的報文以達到節省帶寬加速響應的目的。java

下面簡單介紹一個HTTP使用Gzip壓縮的過程。nginx

  • 瀏覽器發送Http request 給Web服務器, request 中有Accept-Encoding: gzip, deflate, br。 (告訴服務器,瀏覽器支持gzip壓縮)web

  • Web服務器接到request後, 先生成原始的Response, 其中有原始的Content-Type和Content-Length。正則表達式

  • Web服務器經過Gzip,來對Response進行編碼, 編碼後header中有Content-Type和Content-Length(壓縮後的大小), 而且增長了Content-Encoding:gzip. 而後把Response發送給瀏覽器。算法

  • 瀏覽器接到Response後,根據Content-Encoding:gzip來對Response進行解碼。 獲取到原始response後, 而後顯示出網頁。spring

客戶端也能夠發送壓縮數據給服務端,經過代碼將請求數據解壓便可,規範起見一樣要在請求中加入Content-Encoding:gzipjson

用Nginx實現HTTP壓縮

Nginx提供了對HTTP Gzip壓縮的支持,這邊咱們就來看看適應Nginx怎麼對返回報文進行壓縮。

Nginx中經過ngx_http_gzip_module模塊、ngx_http_gzip_static_module模塊和ngx_http_gunzip_module模塊來對Gzip功能進行支持。通常狀況下Nginx默認會編譯
這些模塊,能夠經過nginx -V命令看下你安裝的nginx是否包含了這些模塊。

Gzip相關的指令能夠在配置文件的http塊、server塊或者location塊中

ngx_http_gzip_module模塊

ngx_http_gzip_module模塊主要負責Gzip功能的開啓和設置,對響應數據進行在線實時壓縮。該模塊包含如下主要指令。

# 開啓或者關閉Gzip功能,默認狀況下,該指令設置爲off,即不啓用Gzip功能。只有將該指令設置爲on時,其餘指令設置纔有效
gzip on | off

# 設置Gzip壓縮文件使用緩存空間的大小
# 默認值是:gzip_buffers 32 4k|16 8k
gzip_buffers number size;

# 該指令用於設定Gzip壓縮程度,包括級別1到級別9。
# 級別1表示壓縮程度最低,壓縮效率最高;級別9表示壓縮程度最高,壓縮效率最低,最費時間。
# 默認是1
gzip_comp_level level

# 針對不一樣種類客戶端發起的請求,能夠選擇性地開啓和關閉Gzip功能。
# 支持正則表達式,其中,regex 根據客戶端的瀏覽器標誌(User-Agent,UA)進行設置。
gzip_disable regex ...;

# 該設置使用了正則表達式,其能夠匹配UC字符串中包含MSIE 四、MSIE 5和MSIE6的全部瀏覽器。
# 響應這些瀏覽器發出的請求時,Nginx服務器不進行Gzip壓縮。
gzip_disable MSIE [4-6]\.;

# 早期的一些瀏覽器或者HTTP客戶端,可能不支持Gzip自解壓,所以用戶有時會看到亂碼,因此針
# 對不一樣的HTTP協議版本,須要選擇性地開啓或者關閉Gzip功能。該指令用於設置開啓Gzip功能的最低HTTP協議版本。
# 默認設置爲1.1版本,即只有客戶端使用1.1及以上版本的HTTP協議時,才使用Gzip功能對響應輸出數據進行壓縮。
# 從目前來看,絕大多數的瀏覽器都支持Gzip自解壓,通常採用默認值便可.
zip_http_version 1.0 | 1.1;

# 該指令設置頁面的字節數,當響應頁面的大小大於該值時,才啓用Gzip功能。
# 建議設置成gzip_min_length 1024;
gzip_min_length length;

# 用於設置Nginx服務器是否對後端服務器返回的結果進行Gzip壓縮;
# 通常狀況下,後端都是用來作restAPI接口,返回的數據量不會太大,不建議進行壓縮
# 真的須要對後端返回的數據進行壓縮是能夠再看下這塊的內容
gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any ...;

# 設置MIME類型,被設置的類型將被壓縮,默認值是:text/html
# 該變量還能夠取「*」,表示對全部MIME類型的頁面數據進行Gzip壓縮
# 通常能夠設置成:gzip_types text/plain  application/javascript  text/css text/xml
gzip_types mime-type ...;

# 開啓後的效果是在響應頭部添加了Accept-Encoding: gzip
gzip_vary on | off;

ngx_http_gzip_static_module模塊

ngx_http_gzip_static_module模塊主要負責搜索和發送通過Gzip功能預壓縮的數據。這些數據以「.gz」做爲後綴名存儲在服務器上。若是客戶端請求的數據在以前被壓縮過,而且客戶端瀏覽器支持Gzip壓縮,就直接返回壓縮後的數據。

該模塊與ngx_http_gzip_module模塊的不一樣之處主要在於,該模塊使用的是靜態壓縮,在HTTP響應頭部包含Content-Length頭域來指明報文體的長度,用於服務器可肯定響應數據長度的狀況;然後者默認使用Chunked編碼的動態壓縮,其主要適用於服務器沒法肯定響應數據長度的狀況,好比大文件下載的情形,這時須要實時生成數據長度。

該模塊指令的使用和ngx_http_gzip_static_module模塊相似,這邊就再也不具體展開了。你們能夠參考官方文檔

該模塊是Nginx服務器的可選HTTP模塊,若是要使用,必須在Nginx程序配置時添加--with-http_gzip_static_module指令。

ngx_http_gunzip_module模塊

Nginx服務器支持對響應輸出數據流進行Gzip壓縮,這對客戶端瀏覽器來講,須要有能力解壓和處理Gzip壓縮數據,但若是客戶端自己不支持該功能,就須要Nginx服務器在向其發送數據以前先將該數據解壓。這些壓縮數據可能來自於後端服務器壓縮產生或者Nginx服務器預壓縮產生。ngx_http_gunzip_module模塊即是用來針對不支持Gzip壓縮數據處理的客戶端瀏覽器,對壓縮數據進行解壓處理的.

一樣,對這個模塊的指令使用就不具體展開了,你們能夠參考官方文檔

現代的瀏覽器通常都支持壓縮功能,因此這個模塊使用到的概率較小。

配置列子

gzip            on;
gzip_min_length 1000;
gzip_proxied    expired no-cache no-store private auth;
gzip_types      text/plain application/xml;

爲了使得Nginx服務器可以在全局範圍內應用Gzip壓縮功能,能夠將Gzip配置放在了http全局塊中。若是要對各個虛擬主機差異性對待,咱們能夠在對應的server
塊中添加各自的Gzip配置指令;

閱讀延伸

平時開發的應用中可能不是全部的應用都使用了Nginx,看看其餘Web服務器怎麼開啓對HTTP壓縮的支持。

1. Spring Boot中內嵌的Tomcat開啓壓縮功能

Tomcat做爲servet容器+http server,也是支持gzip壓縮的。使用傳統的Tomcat的話,咱們只須要在server.xml配置開啓HTTP壓縮便可。
在embed版本下須要經過代碼來配置。spring-boot內置的tomcat是embed版本,經過內置的autoconfig機制已經作了一些默認tomcat配置,可是對於一些不經常使用/高級的配置,spring-boot並無提供入口。

不過因爲spring bean的特性,能夠覆蓋默認裝配的bean,包括tomcat相關的配置。使用TomcatConnectorCustomizer接口能夠開啓壓縮配置。

public class ConnC1 implements TomcatConnectorCustomizer{

    @Override
    public void customize(Connector connector) {
        ProtocolHandler protocolHandler = connector.getProtocolHandler();
        if(protocolHandler instanceof Http11NioProtocol){
            Http11NioProtocol http11NioProtocol = (Http11NioProtocol)protocolHandler;
            http11NioProtocol.setCompression("on");//default off
            http11NioProtocol.setCompressibleMimeType();
            http11NioProtocol.setCompressionMinSize(2048);//default 2048(B)
            http11NioProtocol.setMaxKeepAliveRequests(1);//default 200
        }
    }
}

關於Tomcat對於HTTP壓縮的支持,你們能夠從Tomcat的CompressionConfig這個類開始尋找線索。

其實若是隻是簡單開啓對壓縮功能的支持的話,只要在Spring Boot作下面的配置便可:

server:
  compression:
    enabled: true
    min-response-size: 1024
    mime-types:
       application/json

問題

歡迎你們留言說說Gzip功能還有哪些經常使用場景~

相關文章
相關標籤/搜索