问题描述
CDN源站是Nginx服务器,开启了Gzip压缩功能,当客户端直接请求源站时,Gzip压缩功能正常;当客户端的请求回源时,Gzip压缩功能失效,详情如下:
支持Gzip压缩/解压缩时,Nginx将返回压缩后的内容,以降低流量开销,加快响应速度。但是启用CDN后,请求将通过CDN进行转发,而客户端最终收到的是未压缩的内容,即CDN回源后,源站的Gzip功能未生效,详情如下:
- 未启用CDN
请求头(Request Header)含有Accept-Encoding: gzip, deflate
,响应头(Response Header)正常返回Content-Encoding: gzip
,即内容已经被压缩。 - 启用CDN后
请求头含有Accept-Encoding: gzip, deflate
,但响应头返回的是Content-Length
,并未响应Content-Encoding: gzip
。
问题原因
源站Nginx服务器中Gzip相关配置错误,CDN的回源请求未启用Gzip压缩功能,详情如下:
客户端请求经过CDN转发至源站时,回源的请求头中将增加Via
字段以标识请求来自代理服务器(此处指CDN)。而Nginx的ngx_http_gzip_module
模块中存在一个gzip_proxied
配置,此配置专门用于控制代理服务器的请求是否启用Gzip压缩,并且此配置生效的前提之一是请求头中含有Via
字段。由此可见,gzip_proxied
配置将决定回源的请求是否启用Gzip压缩。
解决方案
如果您遇到的问题与问题描述中的情况完全一致,则可以参考下列步骤更新Nginx的配置文件,以修复此问题。如果您无法确定问题现象,可参见更多信息进行排查。
- 找到Nginx中含有Gzip的配置段。由于Gzip可配置在http、server、location三个配置段中,不同配置段对应的配置文件可能不同,请您以实际配置情况为准,本文以Gzip配置在
nginx.conf
文件的HTTP配置段为例。 - 检查Gzip配置中是否存在
gzip_proxied
配置。如果存在,则修改为以下配置;如果不存在,则添加以下配置。更多有关gzip_proxied
配置的介绍,请参见Nginx的官方文档。说明:当不存在
gzip_proxied
配置时,该配置将使用默认值off
。gzip_proxied any
说明:
any
表示所有来自代理服务器的请求都将启用压缩。 - 保存上述配置后,依次执行下列命令,确认Nginx配置无误,然后重新加载Nginx配置文件。
nginx -t
nginx -s reload - 启用CDN,客户端请求经过CDN转发至源站Nginx服务器后,确认返回的响应头中含有
Content-Encoding: gzip
,即内容被压缩。
更多信息
为确保现场环境中的问题情况与本文的问题描述一致,请参见下列步骤进行测试:
- 登录任意支持
curl
命令的客户端。 - 参考下列命令,通过curl命令直接访问源站,同时增加含有
Accept-Encoding: gzip, deflate
的请求头。curl -voa 'http://[$Domain]/[$Resource]' -x [$Original_Server_IP]:80 -H 'Accept-Encoding: gzip, deflate'
说明:
系统返回类似如下,确认响应头中含有
- [$Domain]:您的域名。
- [$Resource]:网站里某个资源的请求地址,例如一张图片、一个API接口等。
- [$Original_Server_IP]:源站Nginx服务器的公网IP地址。
Content-Encoding: gzip
。 - 参考下列命令,在步骤2命令的基础上,增加一个
Via
字段,模拟请求来自于代理服务器。curl -voa 'http://[$Domain]/[$Resource]' -x [$Original_Server_IP]:80 -H 'Accept-Encoding: gzip, deflate' -H 'Via:xxx'
说明:
系统返回类似如下,确认响应头中返回的是Via
字段使用任意值均可,不影响测试结果,本文以xxx
为例。Content-Length
,并未响应Content-Encoding: gzip
。
相关文档
适用于
- CDN