实验环境
- Nginx 1.15.8 (sb-nginx debian package)
- 后端为 Cloudflare (即支持返回未压缩数据或 gzip br 压缩数据)
- 配置开启 proxy cache, 设置 cache key 为 $host$uri
过程及结果
Nginx 的默认行为
- Chrome 发出请求,accept encoding 为
gzip, deflate, br
- Nginx 转发回源,返回 br 压缩数据,并附带 header vary accept encoding
- Nginx 缓存 br 压缩数据并尊重 vary header, 设置此份缓存仅供 accept encoding header 为
gzip, deflate, br
的客户端使用,否则需再次回源 - curl 发出请求,不支持压缩,accept encoding 为空
- Nginx 重新回源
- curl -H 设定 accept header 为
gzip, br
,虽然这个 header 声明支持 br,但与缓存的gzip, deflate, br
并不相同,仍会回源 - 以上 gzip 同理
优化方案 1. 回源不压缩,缓存未压缩的文件,请求时由 Nginx 按需进行 gzip 或 br 压缩
- 通过配置
proxy_set_header Accept-Encoding "";
覆盖客户端 accept encoding,使回源时后端返回未压缩文件;配置proxy_ignore_headers Vary;
忽略 vary header - 配置
brotli on; gzip on; gzip_vary on;
启用 nginx 端压缩 - Chrome 请求支持 br 压缩,首次回源并返回 br 压缩后数据
- curl 请求不支持任何压缩,从缓存中取得未压缩文件并返回
- curl 请求设定 accept encoding 为 gzip,从缓存中取得未压缩文件并返回 gzip 压缩后文件
优化方案 2. 回源全部接受 gzip 压缩,缓存 gzip 压缩后文件,请求时按需解压 gzip
(缺点是不支持 br,因为 nginx 目前没有类似 gunzip 的解压 br 的模块?)
- 通过配置
proxy_set_header Accept-Encoding "gzip";
覆盖客户端 accept encoding,使回源时后端返回 gzip 压缩文件;配置proxy_ignore_headers Vary;
忽略 vary header - 配置
gzip off; brotli off; gzip_vary off;
, 配置gunzip on;
按需解压。 - Chrome 请求支持 gzip 压缩,首次回源并返回由后端服务器(而非我的 nginx ) gzip 压缩后数据并缓存起来
- curl 请求不支持压缩,从缓存中取得 gzip 压缩后文件并解压返回
写的不是很清晰,因为是刚刚搞出来的,但是应该可以解决一些朋友的疑问,如果有问题还可以继续发在下面。