V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
NGINX
NGINX Trac
3rd Party Modules
Security Advisories
CHANGES
OpenResty
ngx_lua
Tengine
在线学习资源
NGINX 开发从入门到精通
NGINX Modules
ngx_echo
isCyan
V2EX  ›  NGINX

实验记录: Nginx 对 proxy cache 的 gzip br 的压缩处理

  •  
  •   isCyan ·
    bohanyang · 2019-02-22 12:24:26 +08:00 · 2962 次点击
    这是一个创建于 2108 天前的主题,其中的信息可能已经有所发展或是发生改变。

    实验环境

    • Nginx 1.15.8 (sb-nginx debian package)
    • 后端为 Cloudflare (即支持返回未压缩数据或 gzip br 压缩数据)
    • 配置开启 proxy cache, 设置 cache key 为 $host$uri

    过程及结果

    Nginx 的默认行为

    1. Chrome 发出请求,accept encoding 为 gzip, deflate, br
    2. Nginx 转发回源,返回 br 压缩数据,并附带 header vary accept encoding
    3. Nginx 缓存 br 压缩数据并尊重 vary header, 设置此份缓存仅供 accept encoding header 为 gzip, deflate, br 的客户端使用,否则需再次回源
    4. curl 发出请求,不支持压缩,accept encoding 为空
    5. Nginx 重新回源
    6. curl -H 设定 accept header 为 gzip, br,虽然这个 header 声明支持 br,但与缓存的gzip, deflate, br并不相同,仍会回源
    7. 以上 gzip 同理

    优化方案 1. 回源不压缩,缓存未压缩的文件,请求时由 Nginx 按需进行 gzip 或 br 压缩

    1. 通过配置 proxy_set_header Accept-Encoding ""; 覆盖客户端 accept encoding,使回源时后端返回未压缩文件;配置 proxy_ignore_headers Vary; 忽略 vary header
    2. 配置 brotli on; gzip on; gzip_vary on; 启用 nginx 端压缩
    3. Chrome 请求支持 br 压缩,首次回源并返回 br 压缩后数据
    4. curl 请求不支持任何压缩,从缓存中取得未压缩文件并返回
    5. curl 请求设定 accept encoding 为 gzip,从缓存中取得未压缩文件并返回 gzip 压缩后文件

    优化方案 2. 回源全部接受 gzip 压缩,缓存 gzip 压缩后文件,请求时按需解压 gzip

    (缺点是不支持 br,因为 nginx 目前没有类似 gunzip 的解压 br 的模块?)

    1. 通过配置 proxy_set_header Accept-Encoding "gzip"; 覆盖客户端 accept encoding,使回源时后端返回 gzip 压缩文件;配置 proxy_ignore_headers Vary; 忽略 vary header
    2. 配置gzip off; brotli off; gzip_vary off;, 配置 gunzip on; 按需解压。
    3. Chrome 请求支持 gzip 压缩,首次回源并返回由后端服务器(而非我的 nginx ) gzip 压缩后数据并缓存起来
    4. curl 请求不支持压缩,从缓存中取得 gzip 压缩后文件并解压返回

    写的不是很清晰,因为是刚刚搞出来的,但是应该可以解决一些朋友的疑问,如果有问题还可以继续发在下面。

    4 条回复    2019-02-22 14:07:32 +08:00
    isCyan
        1
    isCyan  
    OP
       2019-02-22 12:32:55 +08:00   ❤️ 1
    以上仅仅是这台 nginx 服务器作为最边缘的直接接触客户的情况。
    如果前面还有各种 cdn 或者其他反代的话,也要考虑 cdn 的行为。
    isCyan
        2
    isCyan  
    OP
       2019-02-22 13:42:24 +08:00 via Android   ❤️ 1
    各大 cdn 厂商应该都是沿用 nginx 默认配置因为
    不论是动态资源还是静态资源都能通用,
    也不会带来灾难性的后果
    无非是缓存命中率低一些而已

    目前想到的一个较好的解决办法是
    为 cdn 回源单独设置一个域名
    为这个域名的访问关闭所有压缩
    来提高缓存命中率
    dandycheung
        3
    dandycheung  
       2019-02-22 13:45:12 +08:00 via Android
    很有意义的测试和总结。
    Lax
        4
    Lax  
       2019-02-22 14:07:32 +08:00
    方案 1 是个正常的方案,在这种有命中率的情况下,回源流量多一些仅仅是个很次要的问题。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2858 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 06:37 · PVG 14:37 · LAX 22:37 · JFK 01:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.