Nginx: кешировать сжатые прокси-сервером ответы Brotli

Я включил сжатие Brotli в Nginx для динамически генерируемого, но редко меняющегося ресурса.

Я ожидал, что когда Nginx кэширует ответы восходящего потока, он также кэширует результат сжатия. Таким образом, я предположил, что затраты процессора на включение Brotli будут незначительными. Вместо этого я вижу влияние на производительность, подтвержденное perf top быть родственником Бротли.

Я убедился, что кеширование на вышестоящий сервер работает. Однако 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 ответ

Решение

brotli_comp_level 11;

Это слишком высоко. Рекомендация4 для динамического контента.

Вы не можете делать то, что хотите, с текущими настройками.

Если вы можете просто настроить свой апстрим для поддержки brotli, тогда вы можете кэшировать сжатые ответы от него, поместив$http_accept_encodingкак часть ключа кеша. Однако одного этого будет недостаточно, потому что вам придется нормализовать его значение (подумайте, все возможныеAccept-Encoding входящие заголовки приведут к раздутому и крайне неэффективному кешу).

Если вы действительно заботитесь о клиентах с поддержкой Brotli (теперь, когда большинство браузеров все равно поддерживает Brotli) и максимально возможном уровне сжатия, то вы можете принудительно применить сжатие к восходящему потоку с поддержкой Brotli, предоставив Accept-Encoding: brпри прохождении через прокси, что приведет к тому, что кеш всегда будет иметь ответ, закодированный с помощью brotli. (тогда вам не нужно настраивать ключ кеша). Однако для этого требуется функция, которая в настоящее время недоступна, например, я называю ее unbrotli.

Идея состоит в том, что все идет вверх по течению, говоря "Я хочу закодированный ответ Brotli". Апстрим доставляет ответ в формате Brotlied (конечно, если применимо, например, для текстовых ответов). Но для клиентов, которые поддерживают только gzip или вообще не поддерживают сжатие, файлы должны быть динамически распакованы из Brotli (очень низкая нагрузка на ЦП). Это не так уж и здорово, но число недееспособных клиентов Brotli сокращается.

Другие вопросы по тегам