Cache revalidation using If-None-Match

Maxim Dounin mdounin at mdounin.ru
Tue Jul 15 22:52:03 UTC 2014


Hello!

On Mon, Jul 14, 2014 at 11:37:21PM -0400, S.A.N wrote:

> Nginx 1.7.3, отличная версия, в ней полностью решен вопрос с ETag.
> 
> Но есть мелочи которых очень не хватает, их всего две )
> 
> 1. Нельзя получить от клиента валидаторы (“If-Modified-Since” и
> “If-None-Match”) если файла кеша нет, эта ситуация возникает когда бекенд
> отдавал заголовки Cache-Control: private, для контента который должен
> кешироватся только в браузере (не публичный кеш).
> Проблема решается если в конфиге прописать
> fastcgi_param HTTP_IF_NONE_MATCH      $http_if_none_match     if_not_empty;
> fastcgi_param HTTP_IF_MODIFIED_SINCE  $http_if_modified_since if_not_empty;
> Но тогда будет проблема с публичным кешем, потому что бекенд может получить
> валидаторы от браузера, ответить статусом 304, Cache-Control: public... и
> Nginx положит этот ответ (статусом 304 nobody) в файл своего кеша и будет
> его отдавать всем.
> Я уже писал, про эту проблему
> http://forum.nginx.org/read.php?21,245951,245951#msg-245951
> Хочется её как-то решить.

Самое простое решение этой проблемы - не включать кешироване там, 
где оно не нужно.

> 2. Нельзя переопределить через HTTP заголовки значения директивы
> fastcgi_cache_use_stale и установить для кеширования max-age=0
> Для чего это нужно, в конфиге прописывается директива
> fastcgi_cache_use_stale error, это значения нужно для 80% uri.
> Но есть динамические страницы, которые нужно кешировать, но обязательно
> проводить ревалидацию на каждый запрос.
> Пример из жизни где мы это юзаем.
> Есть страница отчетов с графиками различной статистики, которая может
> меняться раз в сутки или каждую секунду, заранее это не известно. Доступ к
> этим отчетам имеют только залогиненые пользователи из определенных групп.
> Кол-во этих юзеров довольно высоко и количество запросов к этим отчетам так
> же высоко, по этому есть смысл их кешировать, но отдавать только после
> проведения проверка на вхождения юзара в нужную групу и на актуальность
> валидаторов (ETag).
> Есть способ как создать кеш с max-age=0, через X-Accel-Expires: $time-1.
> Но нет способа как динамически, сказать Nginx не использовать
> cache_use_stale для этого uri, прописать в конфиге все варианты этих uri
> сложно они динамические и не шаблонные, добавлять какой-то спец признак по
> которому можно создать общий location в принципе можно, но хочется более
> красивого и системного решения. На мой взгляд таким решением может стать
> Cache-Control: must-revalidate, если бекенд отдает этот заголовок, он
> сохраняется в кеш, но при повторном использовании кеша, Nginx всегда
> выполняет ревалидацию (must-revalidate), если бекенд не работает отдать
> клиенту статус ошибки. Это конечно будет иметь определенный оверхед, но
> такой кеш намного эффективней, чем каждый раз повторно генерировать отчет и
> все графики.

Если я правильно понял этот поток текста, то на выходе вы хотите 
получить что-то вроде "The stale-if-error Cache-Control 
Extension", http://tools.ietf.org/html/rfc5861#section-4.  Т.е. 
возможность задать в заголовках ответа - можно ли этот ответ в 
дальнейшем использовать при ошибках.

(Планов по реализации соответствующего расширения - по крайней 
мере в ближайшем будущем - нет.)

IMHO, простейшее и наиболее правильное решение - опять же, 
разделить сайт на location'ы и задать для каждого locatin'а нужные 
настройки.  А если у вас соответствующие ресурсы нельзя нормально 
отделить друг от друга - это повод задуматься о структуре сайта.

-- 
Maxim Dounin
http://nginx.org/



Подробная информация о списке рассылки nginx-ru