Nginx: кэш Brotli, сжатый проксированный ответ восходящего потока - PullRequest
0 голосов
/ 24 января 2020

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

Я ожидал, что когда Nginx кэширует отклики в восходящем направлении, он также будет кэшировать результат сжатия. Таким образом, я предположил, что стоимость процессора для включения Brotli будет незначительной. Вместо этого я вижу снижение производительности, подтвержденное 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 Ответ

1 голос
/ 25 января 2020

brotli_comp_level 11;

Это слишком высоко. Для динамического c содержимого рекомендуется 4.

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

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

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

Идея состоит в том, что все идет вверх по течению, говоря: «Я хочу закодированный Бротли ответ». Верхний поток предоставляет Brotli-ed ответ (где это применимо, конечно, например для текстовых ответов). Но для клиентов, которые поддерживают только gzip или вообще не используют сжатие, вещи должны динамически распаковываться из Brotli (очень низкая нагрузка на процессор). Это не так уж и здорово, но число неспособных клиентов Brotli уменьшается.

...