一篇文章讀懂nginx的gzip功能
前言
HTTP中包體【body】壓縮協(xié)商對(duì)應(yīng)的頭字段為Accept-Encoding/Content-Encoding。對(duì)于HTTP包體壓縮,Nginx的ngx_http_gzip_module模塊提供了動(dòng)態(tài)gzip壓縮功能,并且有很精細(xì)的控制。
包括:
- 開啟關(guān)閉gzip壓縮: gzip on|off
- 對(duì)指定類型的文件進(jìn)行壓縮: gzip_types
- 文件最小壓縮閾值: gzip_min_length
- 設(shè)置壓縮率: gzip_comp_level
- 查看壓縮率: $gzip_ratio
- 是否插入Vary: Accept-Encoding頭字段: gzip_vary
- 禁止指定瀏覽器使用壓縮:gzip_disable
- 是否對(duì)代理請(qǐng)求響應(yīng)壓縮:gzip_proxied
關(guān)于Nginx gzip基本功能,其語(yǔ)義,邏輯,配置和使用都相當(dāng)簡(jiǎn)單,網(wǎng)上相關(guān)文章也很多,本文不再贅述,具體細(xì)節(jié)可以參看下文的配置實(shí)例及說明。本文將重點(diǎn)討論其中的gzip_proxied指令的語(yǔ)義和使用,其涉及若干個(gè)參數(shù),特定的應(yīng)用場(chǎng)景,最為復(fù)雜,且網(wǎng)上文章涉及不多。
語(yǔ)義:
gzip_proxied的基本邏輯是對(duì)于代理請(qǐng)求,根據(jù)請(qǐng)求及回應(yīng)的頭字段決定是否壓縮響應(yīng)包體。判斷的依據(jù)是請(qǐng)求頭中是否攜帶Via頭字段。
如:
拓?fù)洌?/h2>
對(duì)應(yīng)的典型網(wǎng)絡(luò)拓?fù)淙缦拢?/p>
client — proxy1 — proxy2 — … proxyn — reverse proxy — origin web
我們的配置點(diǎn)在reverse proxy上, 也就是企業(yè)提供對(duì)外WEB服務(wù)的邊緣的反向代理服務(wù)器。通常,proxyx會(huì)通過Via頭字段標(biāo)記消息自己的版本號(hào)和名稱,從而形成了一條有序的消息路徑,方便排錯(cuò)。
這是一個(gè)取自京東首頁(yè)的Via字段的值,表示博主訪問京東首頁(yè)中間經(jīng)過了2臺(tái)代理服務(wù)器。
Via: http/1.1 ORI-CLOUD-HEN-MIX-109 (jcs [cSsSfU]), http/1.1 HENzhengzhou-CT-1-MIX-34 (jcs [cRs f ])
仿真:
我們可以通過在curl中添加頭字段Via,模擬該場(chǎng)景。
curl -H 'Via: 1.1 aaa' test/200_accept_encoding.css --compressed -I
驗(yàn)證:
響應(yīng)包體是否壓縮,可以curl -I查看響應(yīng)頭中是否有Content-Encoding: gzip
如:
HTTP/1.1 200 OK Server: nginx/1.20.1 Date: Fri, 18 Feb 2022 03:25:26 GMT Content-Type: text/css Last-Modified: Tue, 08 Feb 2022 15:48:26 GMT Connection: keep-alive Vary: Accept-Encoding ETag: W/"620290ca-3523" Content-Encoding: gzip
壓縮率可以查看log
tail -f ../logs/200_accept_encoding_access.log 47151 192.168.31.133 - - [18/Feb/2022:10:08:07 +0800] "GET /200_accept_encoding.css HTTP/1.1" 200 2646 "-" "curl/7.61.1" "-" 5.16
其中5.16就是壓縮率
本文使用的是nginx 1.20.1, 客戶端工具是curl 7.61.1, 測(cè)試文件為200_accept_encoding.css,可自行選擇任意文件測(cè)試。
[root@test01 conf]# nginx -v nginx version: nginx/1.20.1 [root@test01 conf]# curl -V curl 7.61.1 (x86_64-redhat-linux-gnu) libcurl/7.61.1 OpenSSL/1.1.1k zlib/1.2.11 brotli/1.0.6 libidn2/2.2.0 libpsl/0.20.2 (+libidn2/2.2.0) libssh/0.9.4/openssl/zlib nghttp2/1.33.0
gzip_proxied的參數(shù)解析:
- off gzip_proxied的缺省參數(shù)是off,語(yǔ)義是不對(duì)代理請(qǐng)求的回應(yīng)進(jìn)行壓縮。
- any 對(duì)任意代理請(qǐng)求回應(yīng)壓縮,語(yǔ)義正好和off相反。
- expired 如果回應(yīng)中包含頭字段Expires,并且其值響應(yīng)導(dǎo)致不會(huì)緩存,則壓縮。因此可以構(gòu)造緩存不過期,緩存過期2種場(chǎng)景,分別驗(yàn)證?;貞?yīng)中添加Expires頭字段可以用expires指令。
#expires 1h; #緩存有效期1小時(shí) --->不壓縮 #expires epoch;#緩存有效期設(shè)為1970年1月1日0時(shí),即必然過期,不緩存 --->壓縮
- no-cache no-store private 此3個(gè)參數(shù)有類似的行為和語(yǔ)義,放在一起說,語(yǔ)義是如果響應(yīng)頭字段包含Cache-Control: xxx,xxx是上述參數(shù)中的一個(gè),則壓縮。
注:響應(yīng)中需要顯示地?cái)y帶Cache-Control頭字段,如果不包含則壓縮。
#gzip_proxied no-cache; #gzip_proxied no-store; #gzip_proxied private;
響應(yīng)中添加Cache-Control頭字段用add_header指令
#add_header Cache-Control no-store; #add_header Cache-Control no-cache; #add_header Cache-Control private;
可以同時(shí)設(shè)置多個(gè)gzip_proxied條件:
#gzip_proxied no-cache no-store private;
add_header也可以為Cache-Control設(shè)置多個(gè)值,對(duì)于這種有沖突的Cache-Control設(shè)置,以最嚴(yán)格的限制為準(zhǔn),如本例是no-store生效。
#add_header Cache-Control no-store,no-cache,private;
- no_etag 語(yǔ)義是如果回應(yīng)中不包含頭字段ETag,則壓縮。
ETag默認(rèn)打開,用etag off可以關(guān)閉。
#etag off;
- no_last_modified 語(yǔ)義是如果回應(yīng)中不包含頭字段Last_modified,則壓縮。
#未找到關(guān)閉last_modified的方法,abort。
- auth 語(yǔ)義是請(qǐng)求中包含Authorization時(shí)壓縮
配置下面2條指令可以仿真基本網(wǎng)頁(yè)認(rèn)證:
#auth_basic "test for auth_basic"; #auth_basic_user_file ../src/usr;
小結(jié):
- gzip_min_length的優(yōu)先級(jí)高于gzip_proxied,如果由于gzip_min_length的設(shè)置導(dǎo)致不壓縮,則gzip_proxied即使?jié)M足壓縮條件也不會(huì)壓縮。
- 上述gzip_proxied的參數(shù),除auth是看請(qǐng)求頭字段,其它都是看響應(yīng)頭字段。
- off, any是一對(duì)互斥參數(shù),表達(dá)了對(duì)代理請(qǐng)求是全部不壓縮,或全部壓縮兩種相反的語(yǔ)義。
- no-cache,no-restore,priviate,no_etag,no_last_modified,都和緩存相關(guān),表達(dá)的語(yǔ)義可以歸納為如果響應(yīng)不緩存,則壓縮,其區(qū)別只在于判斷的條件的差異,當(dāng)然,也可以一次性都設(shè)置上。那么為何響應(yīng)不緩存就壓縮呢?官方文檔沒有描述,博主推測(cè)和使用場(chǎng)景有關(guān)。
a. 不緩存意味著不會(huì)在代理服務(wù)器上保留響應(yīng)副本,那么應(yīng)該盡早在消息源頭壓縮,減少鏈路上的帶寬消耗。
b. gzip是CPU密集型的使用,如果響應(yīng)緩存,則可以選擇在下游代理服務(wù)器上啟用壓縮,從而分擔(dān)上游服務(wù)器的壓力。
下面是具體的配置,實(shí)踐實(shí)踐再實(shí)踐才是理解和領(lǐng)會(huì)相關(guān)指令和參數(shù)最有效的方法。
配置文件:
log_format gzip '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" $gzip_ratio';
server {
listen 80;
server_name test test1;
root html;
access_log logs/200_accept_encoding_access.log gzip;
error_log logs/200_accept_encoding_error.log debug;
default_type text/plain;
#gzip off;#這是設(shè)置為off,原因是我在http級(jí)別已經(jīng)把gzip打開了。
gzip_buffers 16 8k;# gzip_buffers number size;
gzip_comp_level 6;#設(shè)置壓縮級(jí)別,缺省為1,可以不用改,級(jí)別6大約和gzip命令行缺省壓縮率相當(dāng)。
#gzip_disable "(Chrome|curl|Firefox)";#根據(jù)User-Agent的返回值,針對(duì)特定客戶端禁止壓縮。這里把3種客戶端都禁了。
#Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
#curl/7.61.1
#Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:97.0) Gecko/20100101 Firefox/97.0
#gzip_http_version 1.1;#指定gzip壓縮針對(duì)的HTTP版本
#gzip_min_length 13603;#設(shè)定最小待壓縮的文件大小,大小的依據(jù)是Content-Length,使用的測(cè)試文件為200_accept_encoding.css
gzip_min_length 620;#index.html文件大小正好是620
#gzip *可以表示所有文件類型
gzip_types application/javascript application/x-javascript text/css *;
#mp4有專屬的mime類型,video/mp4,而不是application/octet-stream,可以在conf/mime.types中查看詳細(xì)的mime類型。
#gzip_types application/javascript application/x-javascript text/css application/octet-stream;
#gzip_types application/javascript application/x-javascript text/css video/mp4;
gzip_vary on;#控制是否插入Vary: Accept-Encoding頭字段。
#gzip_proxied off;#設(shè)置是否壓縮代理請(qǐng)求的回應(yīng),代理請(qǐng)求的依據(jù)是請(qǐng)求頭中是否包含Via字段,off表示只要請(qǐng)求頭中包含Via字段,則不壓縮。
#gzip_proxied expired;#如果回應(yīng)中包含頭字段Expires,并且其值導(dǎo)致不會(huì)緩存,則壓縮。
#注1:該設(shè)置不考慮是否在請(qǐng)求中包含Via
#注2:注1理解是錯(cuò)誤的,進(jìn)入gzip_proxied的先決條件一定是頭字段中包含Via字段,以當(dāng)前的設(shè)置,在不考慮gzip_proxied影響的情況下,響應(yīng)一定是壓縮的,所以給人以誤解,當(dāng)gzip_proxied條件滿足時(shí)無論是否有Via都?jí)嚎s。
#回應(yīng)中添加Expires,注:使用expires指令會(huì)同時(shí)添加Expires和Cache-Control頭字段
#expires 1h; #緩存有效期1小時(shí)
#expires epoch;#緩存有效期設(shè)為1970年1月1日0時(shí),即必然過期,不緩存
#gzip_proxied no-cache no-store private有類似的行為,如果響應(yīng)頭字段包含Cache-Control: xxx,則壓縮
#有2點(diǎn)需要注意,1.受Via字段影響;2.回應(yīng)中需要顯示地有Cache-Control頭字段,如果不包含則壓縮
#gzip_proxied no-cache;
#gzip_proxied no-store;
#gzip_proxied private;
#回應(yīng)添加Cache-Control用add_header
#add_header Cache-Control no-store;
#add_header Cache-Control no-cache;
#add_header Cache-Control private;
#可以同時(shí)設(shè)置多個(gè)gzip_proxied條件:
#gzip_proxied no-cache no-store private;
#add_header也可以為Cache-Control設(shè)置多個(gè)值,對(duì)于這種有沖突的Cache-Control設(shè)置,以最嚴(yán)格的限制為準(zhǔn)。
#add_header Cache-Control no-store,no-cache,private;
#gzip_proxied no_etag;#如果回應(yīng)中不包含頭字段ETag,則壓縮。
#etag off;
#未找到關(guān)閉last_modified的方法,abort
#gzip_proxied no_last_modified;
#if_modified_since off;
#gzip_proxied any;#對(duì)任意代理請(qǐng)求回應(yīng)壓縮。
gzip_proxied auth;#請(qǐng)求中包含Authorization時(shí)壓縮
auth_basic "test for auth_basic";
auth_basic_user_file ../src/usr;
#curl -H 'Via: 1.1 aaa' test --compressed --basic -u root:root
#curl可以使用2種命令行方式驗(yàn)證gzip,一種是添加Accept-Encoding頭字段,一種使用compressed參數(shù)
#curl -H 'Accept-Encoding: gzip' test/200_accept_encoding.css --output a.css
#curl test/200_accept_encoding.css --compressed
#如果客戶端請(qǐng)求不支持的壓縮方式如br,則服務(wù)器將忽略之
location / {
#return 200 'ok\n';#如果使用return,則在gzip模塊生效之前就退出,所以不會(huì)壓縮。
#Content-Length和Cotnent-Encoding不會(huì)同時(shí)出現(xiàn),因?yàn)間zip是實(shí)時(shí)動(dòng)態(tài)壓縮,無法預(yù)先取得Content-Length。
#Accept-Encoding實(shí)驗(yàn)中curl必須顯示的添加Accept-Encoding頭字段,否則視為不使用壓縮方式返回響應(yīng),而瀏覽器天然會(huì)添加Accept-Encoding
#$gzip_ratio計(jì)算的是源文件和壓縮文件的大小之比,如源文件100,壓縮文件20,則ratio為5
}
}
相關(guān)文章:一文讀懂nginx gzip_static
總結(jié)
到此這篇關(guān)于一篇文章讀懂nginx中g(shù)zip功能的文章就介紹到這了,更多相關(guān)nginx gzip功能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Nginx中的Rewrite的重定向配置與實(shí)踐
這篇文章主要介紹了詳解Nginx中的Rewrite的重定向配置與實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03
Nginx配置動(dòng)態(tài)代理后通過curl訪問報(bào)403問題
本文主要介紹了Nginx配置動(dòng)態(tài)代理后通過curl訪問報(bào)403問題,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06
阿里云國(guó)際版使用Nginx作為HTTPS轉(zhuǎn)發(fā)代理服務(wù)器的處理方法
本文介紹了使用NGINX作為HTTPS流量轉(zhuǎn)發(fā)代理的兩種方法。它總結(jié)了NGINX使用HTTP?CONNECT隧道和NGINX流充當(dāng)HTTPS轉(zhuǎn)發(fā)代理的解決方案的原則,環(huán)境構(gòu)建要求,應(yīng)用場(chǎng)景和關(guān)鍵問題2022-05-05
利用nginx與ffmpeg搭建流媒體服務(wù)器過程詳解
這篇文章主要給大家介紹了利用nginx與ffmpeg搭建流媒體服務(wù)器的全過程,文中介紹的很詳細(xì),對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來一起看看吧。2017-03-03

