Nginx + proxy_cache + ssi
Maxim Dounin
mdounin на mdounin.ru
Вт Июл 5 15:06:41 MSD 2011
Hello!
On Mon, Jul 04, 2011 at 11:48:53AM -0400, sergeyarl wrote:
> Всем привет!
> Вопрос возможно глупый, и я не совсем
> понимаю что делаю, но тем не менее прошу
> помощи комьюнити.
> В данный момент пытаюсь разобраться с
> кешированием динамического контента в
> бекенде при помощи nginx. Т.е. proxy_cache и все
> что с этим связанно.
> Цель в принципе тривиальная - всем
> пользователям отдавать кешированную
> страницу, а тем, у кого установлена
> специальная кука отдавать уже контент
> напрямую с бекенда (в моем случае apache +
> php).
> Но есть одно но - куку нужно
> устанавливать с той же страницы,
> которую собираюсь кешировать. Т.е.
> нужно кешировать все, кроме блока на
> странице, который управляет установкой
> куки. Поискал на просторах интернета и
> нашел, что подобное можно сделать при
> помощи ssi в nginx. Т.е. блок, который мне не
> нужно кешировать предлагают вывести в
> отдельный инклуд, а в основном файле
> сделать на него ссылку вида:
> <!--# include virtual="/link/" -->
>
> Собственно это я и пытаюсь сделать у
> себя на тестовом стенде. Разбил
> страницу на два файла - один - index.php -
> страница которую нужно кешировать,
> второй - cookie.php - шапка страницы,
> содержащая интерфейс установки куки
> (TestCookie ).
Так работать не будет: загловок Set-Cookie из include пользователю
не уйдёт, к моменту обработки include'ов заголовки уже отправлены
пользователю. Можно попробовать сделать наоборот: основной запрос
не кешировать и возвращать в нём куку + include на тело, которое
кешировать.
> Пока в nginx не включено кеширование
> инклуд работает, отправляет запросы в
> бекенд и я вижу контент в браузере. Как
> только включаю кеширование в nginx - то в
> браузере получаю пустую страницу, а в
> логе nginx следующее:
> 2011/07/03 04:22:48 [alert] 2420#0: *3 http request count is zero,
> client: 192.168.1.2, server: , request: "GET / HTTP/1.1", subrequest:
> "/cookie.php", host: "192.168.1.4", referrer: "http://192.168.1.4/"
[...]
> proxy_cache_key
> "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri";
У вас в proxy_cache_key стоит $request_uri, т.е. URI исходного
запроса. Соответственно кеш будет отдавать тот же ответ и для
подзапроса /cookie.php, и таким образом имеем бесконечный цикл.
Вот тут есть патч, который делает более внятную защиту от подобных
циклов:
http://nginx.org/pipermail/nginx-devel/2011-June/001001.html
Но картина будет отличаться только тем, насколько корректно nginx
расскажет вам об этой ошибке.
Maxim Dounin
Подробная информация о списке рассылки nginx-ru