Nginx:缓存Brotli压缩代理上游响应

时间:2020-01-24 15:25:17

标签: nginx brotli ngx-brotli

我在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;
  }
}

1 个答案:

答案 0 :(得分: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的客户端数量正在下降。