Nginx:cache Brotli压缩的代理上游响应

Nginx:cache Brotli压缩的代理上游响应,nginx,brotli,ngx-brotli,Nginx,Brotli,Ngx Brotli,我在Nginx中为动态生成但很少更改的资源启用了Brotli压缩 我的期望是,当Nginx缓存上游响应时,它也会缓存压缩结果。因此,我假设启用Brotli的CPU成本可以忽略不计。相反,我看到了一个与Brotli相关的性能影响,由perf top确认 我验证了上游服务器的缓存是否有效。但是,Nginx只在其缓存中存储未压缩的上游请求。因此,它必须为每个请求运行代价高昂的Brotli压缩。这就是问题所在 有消息来源(与gzip压缩相关)建议在上游进行压缩,或者如果这不是创建第二个Nginx代理请求

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

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

我验证了上游服务器的缓存是否有效。但是,Nginx只在其缓存中存储未压缩的上游请求。因此,它必须为每个请求运行代价高昂的Brotli压缩。这就是问题所在

有消息来源(与gzip压缩相关)建议在上游进行压缩,或者如果这不是创建第二个Nginx代理请求的选项,则建议使用第二个Nginx代理请求,该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;
  }
}
brotli_公司11级

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

您无法使用当前设置执行所需的操作

如果您可以将上游设置为支持brotli,那么您可以通过将
$http\u accept\u encoding
作为缓存密钥的一部分来缓存来自上游的压缩响应。但是,单凭这一点还不够好,因为您必须规范化它的值(想想,所有可能的
Accept-Encoding
传入头都会导致缓存臃肿且效率极低)

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


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

我还得出结论,Nginx中没有直接支持缓存压缩内容的功能(可以说,这是一个不错的功能)。我所做的是测量Brotli的开销。11(还有10)相当重,但对于给定的工作负载,9并没有增加显著的开销。仍然不理想,但考虑到目前没有简单的替代方案,我认为这是一个合理的妥协。