1

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

1 回答 1

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 无能力的客户数量正在减少。

于 2020-01-25T10:32:05.180 回答