Кеширование SSI в nginx

izbushka
На сайте с 08.06.2007
Offline
110
4151

Не работает кеширование SSI в nginx.

Получаю ошибку:

2014/07/18 14:02:07 [error] 19843#0: *1 subrequests cycle while processing "/dobovo/apt/inc.php", client: 192.168.0.216, server: , request: "GET /dobovo/apt/test.php HTTP/1.1", subrequest: "/dobovo/apt/inc.php", host: "192.168.0.216"

Сделал специально простой конфиг:

user mirage mirage;
worker_processes 1;

events {
worker_connections 1024;
use epoll;
}

http {
charset utf-8;

fastcgi_cache_path /home/nginx/cache/pagesFCGI keys_zone=cache_zone:10m;
error_log /var/log/nginx/error_log2 debug;

server {
listen 192.168.0.216 default;
root /home/git/front.dobovo.com/www;

include inc/fastcgi.inc;

location / {
ssi on;
fastcgi_pass unix:/run/php-fpm.socket;
fastcgi_cache cache_zone;
fastcgi_cache_valid 200 5s;
fastcgi_cache_key "$request_method$host$request_uri";
}
}
}

Файл test.php:

SSI:<br>                                  
<!--# include virtual="/dobovo/apt/inc.php" -->
<br> *end of ssi*

Файл инклуда:

SSI include

В браузере выглядит так:

SSI:
SSI:
[много строк SSI:]
SSI:
[an error occurred while processing the directive]
*end of ssi*
*end of ssi*
[много строк *end of ssi*]
*end of ssi*

Пробовал с proxy_pass и простыми html-ками - тоже самое (дело не в fastsgi бекэнде)

Файл кеша создается:

��S����������S��#0S�
KEY: GET192.168.0.216/dobovo/apt/test.php
�X-Powered-By: PHP/5.3.28-pl3-gentoo
Content-type: text/html

SSI:<br>

<!--# include virtual="/dobovo/apt/inc.php" -->

<br> *end of ssi*

С выключенным кешем работает.

VK
На сайте с 29.12.2011
Offline
42
#1

izbushka, закэшируйте отдельный локейшен, который будет делать запросы к бэкенду.

izbushka
На сайте с 08.06.2007
Offline
110
#2

V2NEK, Всмысле?

У меня все запросы к бекенду..

И мне надо кешировать и саму страницу и ее инклуды, на разное время

VK
На сайте с 29.12.2011
Offline
42
#3

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

ps. Хороший сервис делаете, привет соседям (:

izbushka
На сайте с 08.06.2007
Offline
110
#4

Да, так работает, но проблема опять появляется когда использую многоуровневые ssi вложения: т.е. включаю ssi внутри ssi.

Что можно сделать в этом случае? Плодить locations? Становится неудобно следить за тем, как именно надо подключать ssi в конкретном месте, чтоб он попал в другой location.

VK
На сайте с 29.12.2011
Offline
42
#5

izbushka, скорее всего ssi внутри ssi и не будет отрабатывать, тк это статические данные и, попав в кэш, они больше не будут как-либо обрабатываться. Тут придется менять уже структуру ресурса.

izbushka
На сайте с 08.06.2007
Offline
110
#6

Нагуглил следующее:

В /test3.php делается инклуд /test2.php, который в свою очередь
достаётся из кеша по ключу, содержащему только $request_uri -
оригинальный uri полученный от клиента, т.е. в данном случае
/test3.php. В результате имеем бесконечный рекурсивный ssi.
Защиты от рекурсии в ssi сейчас нет.

Предлагают юзать $uri вместо $request_uri как ключ кеша, но у меня пока не работает (гуглю).

In the previous config I had caching set for $request_uri. That means nginx will file and fetch caches based on the incoming request. The server side include makes another request but since caching is based on the incoming uri it ends up fetching the main page itself, thus inserting itself repeatedly.
By using $uri instead of $request_uri nginx will respect rewrites and ssi requests thus caching and fetching via appropriate namespaces (in this case the app's defined ssi routes).

Простой вариант, даже не требующий отдельного location для ssi, это включать SSI с GET параметром, указывающим на уровень его вложенности (level=N) и добавить $query_string в ключ кеша.

Читаю дальше, спасибо за наводку, в любом случае

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий