Nginx:缓存 Brotli 压缩代理上游响应
Nginx: cache Brotli compressed proxied upstream responses
我在 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;
}
}
brotli_comp_level 11;
太高了。对于动态内容,建议 4
。
您不能用当前设置做您想做的事。
如果你可以将上游设置为brotli-capable,那么你可以通过将$http_accept_encoding
作为一部分来缓存来自它的压缩响应的缓存键。但是,仅此一点还不够好,因为您必须规范化它的值(想想,所有可能的 Accept-Encoding
传入 headers,将导致臃肿且效率极低的缓存)。
如果你真的关心支持 Brotli 的客户端(现在大多数浏览器都支持 Brotli),以及可能的最高压缩级别,那么你可以
通过提供 Accept-Encoding: br
而 proxy-passing 来强制对 brotli-capable 上游进行压缩,这将导致缓存始终具有 brotli 编码的响应。 (你不需要调整你的缓存键)。但是,这需要一个功能,目前不可用,例如我称之为unbrotli
。
想法是一切都向上游说 "I want Brotli encoded response"。上游提供 Brotli-ed 响应(当然,在适用的情况下,例如对于文本响应)。但对于只支持 gzip 或根本不支持压缩的客户端,应该从 Brotli 中动态解压(非常低 CPU 影响)。这不是很好,但是 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;
}
}
brotli_comp_level 11;
太高了。对于动态内容,建议 4
。
您不能用当前设置做您想做的事。
如果你可以将上游设置为brotli-capable,那么你可以通过将$http_accept_encoding
作为一部分来缓存来自它的压缩响应的缓存键。但是,仅此一点还不够好,因为您必须规范化它的值(想想,所有可能的 Accept-Encoding
传入 headers,将导致臃肿且效率极低的缓存)。
如果你真的关心支持 Brotli 的客户端(现在大多数浏览器都支持 Brotli),以及可能的最高压缩级别,那么你可以
通过提供 Accept-Encoding: br
而 proxy-passing 来强制对 brotli-capable 上游进行压缩,这将导致缓存始终具有 brotli 编码的响应。 (你不需要调整你的缓存键)。但是,这需要一个功能,目前不可用,例如我称之为unbrotli
。
想法是一切都向上游说 "I want Brotli encoded response"。上游提供 Brotli-ed 响应(当然,在适用的情况下,例如对于文本响应)。但对于只支持 gzip 或根本不支持压缩的客户端,应该从 Brotli 中动态解压(非常低 CPU 影响)。这不是很好,但是 Brotli 无能力的客户数量正在减少。