什么是HTTP壓縮
有時候客戶端和服務(wù)器之間會傳輸比較大的報文數(shù)據(jù),這時候就占用較大的網(wǎng)絡(luò)帶寬和時長。為了節(jié)省帶寬,加速報文的響應(yīng)速速,可以將傳輸?shù)膱笪臄?shù)據(jù)先進行壓縮,然后再進行傳輸。
HTTP支持多種報文壓縮算法,下面是一個普通的請求頭,從Accept-Encoding字段可以看出支持gzip、deflate和br壓縮算法。本文我們重點講使用Gzip算法對報文進行壓縮,比如Gzip來壓縮HTML,Javascript, CSS文件,壓縮完后能大大減少網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)量,提高了用戶顯示網(wǎng)頁的速度。
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
任何技術(shù)都是雙面的,HTTP壓縮雖然能減少帶寬占用加快響應(yīng)速度,但是因為需要額外的壓縮和解壓的過程,所以會占用些客戶端或服務(wù)器端的計算資源。
了解HTTP的讀者知道,可以對HTTP的報文體進行編碼加密。其實HTTP壓縮是一種特殊的編碼方式,使用這種編碼方式可以將報文大大減少,使用對應(yīng)的解法方式又能還原最初的報文。(我們可以看出,其實壓縮技術(shù)的本質(zhì)就是一種編碼方式)
HTTP壓縮的使用場景
從上面對于HTTP壓縮的介紹可以看出,這種技術(shù)是一種優(yōu)化技術(shù),常常用于壓縮服務(wù)器端返回的報文以達到節(jié)省帶寬加速響應(yīng)的目的。
下面簡單介紹一個HTTP使用Gzip壓縮的過程。
- 瀏覽器發(fā)送Http request 給Web服務(wù)器, request 中有Accept-Encoding: gzip, deflate, br。 (告訴服務(wù)器,瀏覽器支持gzip壓縮)
- Web服務(wù)器接到request后, 先生成原始的Response, 其中有原始的Content-Type和Content-Length。
- Web服務(wù)器通過Gzip,來對Response進行編碼, 編碼后header中有Content-Type和Content-Length(壓縮后的大小), 并且增加了Content-Encoding:gzip. 然后把Response發(fā)送給瀏覽器。
- 瀏覽器接到Response后,根據(jù)Content-Encoding:gzip來對Response進行解碼。 獲取到原始response后, 然后顯示出網(wǎng)頁。
客戶端也可以發(fā)送壓縮數(shù)據(jù)給服務(wù)端,通過代碼將請求數(shù)據(jù)解壓即可,規(guī)范起見同樣要在請求中加入Content-Encoding:gzip
用Nginx實現(xiàn)HTTP壓縮
Nginx提供了對HTTP Gzip壓縮的支持,這邊我們就來看看適應(yīng)Nginx怎么對返回報文進行壓縮。
Nginx中通過ngx_http_gzip_module模塊、ngx_http_gzip_static_module模塊和ngx_http_gunzip_module模塊來對Gzip功能進行支持。一般情況下Nginx默認會編譯
這些模塊,可以通過nginx -V命令看下你安裝的nginx是否包含了這些模塊。
Gzip相關(guān)的指令可以在配置文件的http塊、server塊或者location塊中。
ngx_http_gzip_module模塊
ngx_http_gzip_module模塊主要負責Gzip功能的開啟和設(shè)置,對響應(yīng)數(shù)據(jù)進行在線實時壓縮。該模塊包含以下主要指令。
# 開啟或者關(guān)閉Gzip功能,默認情況下,該指令設(shè)置為off,即不啟用Gzip功能。只有將該指令設(shè)置為on時,其他指令設(shè)置才有效
gzip on | off
# 設(shè)置Gzip壓縮文件使用緩存空間的大小
# 默認值是:gzip_buffers 32 4k|16 8k
gzip_buffers number size;
# 該指令用于設(shè)定Gzip壓縮程度,包括級別1到級別9。
# 級別1表示壓縮程度最低,壓縮效率最高;級別9表示壓縮程度最高,壓縮效率最低,最費時間。
# 默認是1
gzip_comp_level level
# 針對不同種類客戶端發(fā)起的請求,可以選擇性地開啟和關(guān)閉Gzip功能。
# 支持正則表達式,其中,regex 根據(jù)客戶端的瀏覽器標志(User-Agent,UA)進行設(shè)置。
gzip_disable regex ...;
# 該設(shè)置使用了正則表達式,其可以匹配UC字符串中包含MSIE 4、MSIE 5和MSIE6的所有瀏覽器。
# 響應(yīng)這些瀏覽器發(fā)出的請求時,Nginx服務(wù)器不進行Gzip壓縮。
gzip_disable MSIE [4-6]\.;
# 早期的一些瀏覽器或者HTTP客戶端,可能不支持Gzip自解壓,因此用戶有時會看到亂碼,所以針
# 對不同的HTTP協(xié)議版本,需要選擇性地開啟或者關(guān)閉Gzip功能。該指令用于設(shè)置開啟Gzip功能的最低HTTP協(xié)議版本。
# 默認設(shè)置為1.1版本,即只有客戶端使用1.1及以上版本的HTTP協(xié)議時,才使用Gzip功能對響應(yīng)輸出數(shù)據(jù)進行壓縮。
# 從目前來看,絕大多數(shù)的瀏覽器都支持Gzip自解壓,一般采用默認值即可.
zip_http_version 1.0 | 1.1;
# 該指令設(shè)置頁面的字節(jié)數(shù),當響應(yīng)頁面的大小大于該值時,才啟用Gzip功能。
# 建議設(shè)置成gzip_min_length 1024;
gzip_min_length length;
# 用于設(shè)置Nginx服務(wù)器是否對后端服務(wù)器返回的結(jié)果進行Gzip壓縮;
# 一般情況下,后端都是用來做restAPI接口,返回的數(shù)據(jù)量不會太大,不建議進行壓縮
# 真的需要對后端返回的數(shù)據(jù)進行壓縮是可以再看下這塊的內(nèi)容
gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any ...;
# 設(shè)置MIME類型,被設(shè)置的類型將被壓縮,默認值是:text/html
# 該變量還可以取“*”,表示對所有MIME類型的頁面數(shù)據(jù)進行Gzip壓縮
# 一般可以設(shè)置成:gzip_types text/plain application/javascript text/css text/xml
gzip_types mime-type ...;
# 開啟后的效果是在響應(yīng)頭部添加了Accept-Encoding: gzip
gzip_vary on | off;
ngx_http_gzip_static_module模塊
ngx_http_gzip_static_module模塊主要負責搜索和發(fā)送經(jīng)過Gzip功能預壓縮的數(shù)據(jù)。這些數(shù)據(jù)以“.gz”作為后綴名存儲在服務(wù)器上。如果客戶端請求的數(shù)據(jù)在之前被壓縮過,并且客戶端瀏覽器支持Gzip壓縮,就直接返回壓縮后的數(shù)據(jù)。
該模塊與ngx_http_gzip_module模塊的不同之處主要在于,該模塊使用的是靜態(tài)壓縮,在HTTP響應(yīng)頭部包含Content-Length頭域來指明報文體的長度,用于服務(wù)器可確定響應(yīng)數(shù)據(jù)長度的情況;而后者默認使用Chunked編碼的動態(tài)壓縮,其主要適用于服務(wù)器無法確定響應(yīng)數(shù)據(jù)長度的情況,比如大文件下載的情形,這時需要實時生成數(shù)據(jù)長度。
該模塊指令的使用和ngx_http_gzip_static_module模塊類似,這邊就不再具體展開了。大家可以參考官方文檔
該模塊是Nginx服務(wù)器的可選HTTP模塊,如果要使用,必須在Nginx程序配置時添加--with-http_gzip_static_module指令。
ngx_http_gunzip_module模塊
Nginx服務(wù)器支持對響應(yīng)輸出數(shù)據(jù)流進行Gzip壓縮,這對客戶端瀏覽器來說,需要有能力解壓和處理Gzip壓縮數(shù)據(jù),但如果客戶端本身不支持該功能,就需要Nginx服務(wù)器在向其發(fā)送數(shù)據(jù)之前先將該數(shù)據(jù)解壓。這些壓縮數(shù)據(jù)可能來自于后端服務(wù)器壓縮產(chǎn)生或者Nginx服務(wù)器預壓縮產(chǎn)生。ngx_http_gunzip_module模塊便是用來針對不支持Gzip壓縮數(shù)據(jù)處理的客戶端瀏覽器,對壓縮數(shù)據(jù)進行解壓處理的.
同樣,對這個模塊的指令使用就不具體展開了,大家可以參考官方文檔
現(xiàn)代的瀏覽器一般都支持壓縮功能,所以這個模塊使用到的幾率較小。
配置列子
gzip on;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain application/xml;
為了使得Nginx服務(wù)器能夠在全局范圍內(nèi)應(yīng)用Gzip壓縮功能,可以將Gzip配置放在了http全局塊中。如果要對各個虛擬主機差別性對待,我們可以在對應(yīng)的server
塊中添加各自的Gzip配置指令;
閱讀延伸
平時開發(fā)的應(yīng)用中可能不是所有的應(yīng)用都使用了Nginx,看看其他Web服務(wù)器怎么開啟對HTTP壓縮的支持。
1. Spring Boot中內(nèi)嵌的Tomcat開啟壓縮功能
Tomcat作為servet容器+http server,也是支持gzip壓縮的。使用傳統(tǒng)的Tomcat的話,我們只需要在server.xml配置開啟HTTP壓縮即可。
在embed版本下需要通過代碼來配置。spring-boot內(nèi)置的tomcat是embed版本,通過內(nèi)置的autoconfig機制已經(jīng)做了一些默認tomcat配置,但是對于一些不常用/高級的配置,spring-boot并沒有提供入口。
不過由于spring bean的特性,可以覆蓋默認裝配的bean,包括tomcat相關(guān)的配置。使用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
}
}
}
關(guān)于Tomcat對于HTTP壓縮的支持,大家可以從Tomcat的CompressionConfig這個類開始尋找線索。
其實如果只是簡單開啟對壓縮功能的支持的話,只要在Spring Boot做下面的配置即可:
server:
compression:
enabled: true
min-response-size: 1024
mime-types:
application/json
總結(jié)
到此這篇關(guān)于Nginx的Gzip功能的文章就介紹到這了,更多相關(guān)Nginx的Gzip功能內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!