【问题标题】:Nginx: cache Brotli compressed proxied upstream responsesNginx:缓存 Brotli 压缩的代理上游响应
【发布时间】:2020-01-24 15:25:17
【问题描述】:

我在 Nginx 中为动态生成但很少更改的资源启用了 Brotli 压缩。

我的预期是,当 Nginx 缓存上游响应时,它也会缓存压缩结果。因此,我假设启用 Brotli 的 CPU 成本可以忽略不计。相反,我看到了性能影响,perf top 确认与 Brotli 有关。

我验证了缓存到上游服务器的工作。但是,Nginx 仅在其缓存中存储未压缩的上游请求。因此,它必须为每个请求运行昂贵的 Brotli 压缩。这就是问题所在。

有一些来源(与 gzip 压缩有关)建议在上游进行压缩,或者如果这不是创建第二个 Nginx 来代理请求的选项,它扮演上游的角色并进行压缩。两种解决方案都不是很优雅。

有没有办法让 Nginx 不仅缓存未压缩的上游请求,还缓存压缩的结果?

也许我忽略了一些。这是一个简化的配置:

proxy_cache_path /var/cache/nginx levels=1 keys_zone=my_config_cache:8M
                 inactive=60m use_temp_path=off;

server {
  location = /foo {

    proxy_pass http://test-upstream;
    proxy_http_version 1.1;
    proxy_set_header Connection "";

    proxy_ignore_headers Expires;
    proxy_ignore_headers Cache-Control;

    brotli on;
    brotli_comp_level 11;

    proxy_cache my_config_cache;
    proxy_cache_valid 10s;
    proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;

    expires 60s;
  }
}

【问题讨论】:

    标签: nginx brotli ngx-brotli


    【解决方案1】:

    brotli_comp_level 11;

    太高了。对于动态内容,建议使用 4

    你不能用当前的设置做你想做的事。

    如果您可以将上游设置为支持 brotli,然后您可以缓存来自它的压缩响应,方法是将 $http_accept_encoding 作为缓存键的一部分。然而,仅此还不够好,因为您必须对其值进行规范化(想想,所有可能的 Accept-Encoding 传入标头都会导致缓存膨胀且效率极低)。

    如果您真的关心启用了 Brotli 的客户端(现在大多数浏览器都支持 Brotli)以及可能的最高压缩级别,那么您可以 通过在代理传递时提供Accept-Encoding: br 来强制对支持brotli 的上游进行压缩,这将导致缓存始终具有brotli 编码响应。 (那时你不需要调整你的缓存键)。但是,这需要一个当前不可用的功能,例如我称之为unbrotli

    这个想法是,一切都进入上游说“我想要 Brotli 编码响应”。上游提供 Brotli-ed 响应(当然,在适用的情况下,例如用于文本响应)。但是对于只支持 gzip 或根本不支持压缩的客户端,应该从 Brotli 动态解压缩(CPU 影响非常低)。这不是很好,但是无法使用 Brotli 的客户数量正在减少。

    【讨论】:

    • 我还得出结论,没有直接支持在 Nginx 中缓存压缩内容(可以说,这将是一个不错的功能)。我所做的是测量 Brotli 的开销。 11(以及 10)相当繁重,但对于给定的工作负载,9 并没有增加显着的开销。仍然不理想,但鉴于目前没有简单的替代方案,我认为这是一个合理的折衷方案。
    猜你喜欢
    • 1970-01-01
    • 2022-11-04
    • 1970-01-01
    • 1970-01-01
    • 2013-09-09
    • 2016-11-05
    • 2021-09-15
    • 2021-12-16
    • 2013-10-23
    相关资源
    最近更新 更多