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