Я использую сервер Nginx, который действует как кеш / обратный прокси для моего исходного сервера Apache.
я изо всех сил пытался отладить высокая скорость кеширования MISS
когда я обнаружил, что это потому, что заголовок ответа Vary: Accept-Encoding
, разные клиенты www с разными Accept-Encoding
не получали HIT
, даже если точно такой же URL-адрес был ранее запрошен другим клиентом.
Это можно исправить, добавив конфигурацию nginx:
proxy_ignore_headers Vary;
После этого я получаю HIT
кешировать ответы.
а) Отключает ли это различные варианты кешированных страниц? просто между моим кеш-сервером и исходным сервером? (например, безопасно использовать)
б) Или он кэширует одну версию (файл с gzip или без gzip) для всех конечных клиентов, независимо от возможностей клиентского кодирования / декодирования? Я думаю, это может привести к тому, что клиент, не поддерживающий gzip, получит файл gziped?
Даже если кеш улучшен / исправлен указанной выше директивой, конечный клиент все равно получает Vary: Accept-Encoding
, его можно скрыть с помощью proxy_hide_header Vary
а я должен?
Я провел небольшое расследование по этому поводу. Я думаю, что нашел ценную информацию в обсуждении GitHub в Yichun Zhang (автор форка OpenResty nginx) Ответить:
Предлагаю следующие варианты:
- Кэшируйте как сжатые, так и несжатые ответы и добавьте (в каноническом) значении Accept-Encoding в свой ключ кеша. Таким образом, клиенты, которые не ожидают ответов gzip'd, приводят к пропуску кеша (и запускают кеширование несжатой версии).
- Кэшируйте сжатые ответы и используйте стандартный модуль ngx_gunzip для распаковки тела ответа для тех клиентов, которые не принимают кодировку gzip :. Видеть http://nginx.org/en/docs/http/ngx_http_gunzip_module.html Но вам нужно быть осторожным с порядком выходного фильтра nginx (между фильтром ngx_srcache и фильтром ngx_gunzip).
- Кэшируйте только несжатый контент и полагайтесь на модуль ngx_gzip для сжатия данных для тех клиентов, которые ожидают gzip. Установить proxy_set_header Accept-Encoding ''; например, если прокси-модуль используется в качестве обработчика содержимого.
Похоже, это небезопасно, и вам следует кэшировать оба ответа (сжатый и несжатый).
Но что произойдет, если вы получите несколько запросов со следующими Accept-Encoding
заголовки:
Accept-Encoding: gzip
Accept-Encoding: gzip, br
Accept-Encoding: gzip;q=0.8, br;q=0.9
Accept-Encoding: gzip, deflate, br
Значит ли это, что каждый ответ будет кешироваться отдельно? Я пока не знаю, это требует более обширного тестирования, которое я уже проводил. Что я нашел на данный момент:
Accept-Encoding: deflate
со спущенным ответом (который лишь немного отличается от сжатого с помощью gzip).Accept-Encoding: identity;q=0.8, gzip;q=0.5
заголовок. Если у тебя есть ngx_brotly
установленный модуль, nginx всегда будет отвечать, если ваш Accept-Encoding
заголовок запроса содержит br
метод сжатия независимо от того, какие веса указаны для методов сжатия.Ичунь Чжан упоминает о добавлении (канонического) значения Accept-Encoding в ваш ключ кеша. Это может быть что-то вроде
map $http_accept_encoding $encoding_key {
~[\s:,]br(?:[\s,;]|$) 2; # brotli
~[\s:,]gzip(?:[\s,;]|$) 1; # gzip
default 0; # uncompressed
}
Если вы не используете ngx_brotly
модуль, все можно упростить:
if ($http_accept_encoding ~ "[\s:,]gzip(?:[\s,;]|$)") {
set $encoding_key 1;
}
После этого добавление $encoding_key
переменная для proxy_cache_key
Expression может помочь, но, как я уже сказал, это требует более тщательного тестирования.