請求通過CDN回源后Gzip壓縮不生效?
問題描述
CDN源站是Nginx服務(wù)器,開啟了Gzip壓縮功能,當客戶端直接請求源站時,Gzip壓縮功能正常;當客戶端的請求回源時,Gzip壓縮功能失效,詳情如下:
支持Gzip壓縮/解壓縮時,Nginx將返回壓縮后的內(nèi)容,以降低流量開銷,加快響應(yīng)速度。但是啟用CDN后,請求將通過CDN進行轉(zhuǎn)發(fā),而客戶端最終收到的是未壓縮的內(nèi)容,即CDN回源后,源站的Gzip功能未生效,詳情如下:
未啟用CDN 請求頭(Request Header)含有
Accept-Encoding: gzip, deflate
,響應(yīng)頭(Response Header)正常返回Content-Encoding: gzip
,即內(nèi)容已經(jīng)被壓縮。啟用CDN后 請求頭含有
Accept-Encoding: gzip, deflate
,但響應(yīng)頭返回的是Content-Length
,并未響應(yīng)Content-Encoding: gzip
。
問題原因
源站Nginx服務(wù)器中Gzip相關(guān)配置錯誤,CDN的回源請求未啟用Gzip壓縮功能,詳情如下:
客戶端請求經(jīng)過CDN轉(zhuǎn)發(fā)至源站時,回源的請求頭中將增加Via
字段以標識請求來自代理服務(wù)器(此處指CDN)。而Nginx的ngx_http_gzip_module
模塊中存在一個gzip_proxied
配置,此配置專門用于控制代理服務(wù)器的請求是否啟用Gzip壓縮,并且此配置生效的前提之一是請求頭中含有Via
字段。由此可見,gzip_proxied
配置將決定回源的請求是否啟用Gzip壓縮。
解決方案
如果您遇到的問題與問題描述中的情況完全一致,則可以參考下列步驟更新Nginx的配置文件,以修復(fù)此問題。如果您無法確定問題現(xiàn)象,可參見更多信息進行排查。
找到Nginx中含有Gzip的配置段。由于Gzip可配置在http、server、location三個配置段中,不同配置段對應(yīng)的配置文件可能不同,請您以實際配置情況為準,本文以Gzip配置在
nginx.conf
文件的HTTP配置段為例。檢查Gzip配置中是否存在
gzip_proxied
配置。如果存在,則修改為以下配置;如果不存在,則添加以下配置。更多有關(guān)gzip_proxied
配置的介紹,請參見Nginx的官方文檔。說明當不存在
gzip_proxied
配置時,該配置將使用默認值off
。gzip_proxied any
說明any
表示所有來自代理服務(wù)器的請求都將啟用壓縮。保存上述配置后,依次執(zhí)行下列命令,確認Nginx配置無誤,然后重新加載Nginx配置文件。
nginx -t nginx -s reload
啟用CDN,客戶端請求經(jīng)過CDN轉(zhuǎn)發(fā)至源站Nginx服務(wù)器后,確認返回的響應(yīng)頭中含有
Content-Encoding: gzip
,即內(nèi)容被壓縮。
更多信息
為確保現(xiàn)場環(huán)境中的問題情況與本文的問題描述一致,請參見下列步驟進行測試:
登錄任意支持
curl
命令的客戶端。參考下列命令,通過curl命令直接訪問源站,同時增加含有
Accept-Encoding: gzip, deflate
的請求頭。curl -voa 'http://[$Domain]/[$Resource]' -x [$Original_Server_IP]:80 -H 'Accept-Encoding: gzip, deflate'
說明[$Domain]:您的域名。
[$Resource]:網(wǎng)站里某個資源的請求地址,例如一張圖片、一個API接口等。
[$Original_Server_IP]:源站Nginx服務(wù)器的公網(wǎng)IP地址。
系統(tǒng)返回類似如下,確認響應(yīng)頭中含有
Content-Encoding: gzip
。參考下列命令,在步驟2命令的基礎(chǔ)上,增加一個
Via
字段,模擬請求來自于代理服務(wù)器。curl -voa 'http://[$Domain]/[$Resource]' -x [$Original_Server_IP]:80 -H 'Accept-Encoding: gzip, deflate' -H 'Via:xxx'
說明Via
字段使用任意值均可,不影響測試結(jié)果,本文以xxx
為例。系統(tǒng)返回類似如下,確認響應(yīng)頭中返回的是
Content-Length
,并未響應(yīng)Content-Encoding: gzip
。