Nginx выборочное кеширование

12
T
На сайте с 11.08.2009
Offline
133
1532

Добрый день, подскажите пожалуйста по nginx. Есть стек Nginx + PHP-FMP, нужно прикрутить кеширование, но не всего проекта, а только некоторых определенных маршрутов. Сам проект на php -> Lumen (Laravel)

Например, на сайте есть страница: htttp://site.com/contact, возможно ли средствами nginx закешировать только ее (Что-бы запрос не дошел до backend)?

Сами настройки следующие:


fastcgi_cache_path temp/nginx/cache levels=1:2 keys_zone=MYAPP:100m inactive=120m max_size=10g;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_ignore_headers Expires Cache-Control Set-Cookie;
fastcgi_cache_min_uses 1;

Если подключить кеш в локейшен с php, то кеш работает НО кеширует все запросы (что в принципе и не удивительно)


location / {
try_files $uri $uri/ /index.php?$query_string;
}

location ~ \.php$ {
try_files $uri =404;
include nginx.fastcgi.conf;
include nginx.redis.conf;
fastcgi_pass php_farm;

fastcgi_cache MYAPP;
fastcgi_cache_valid 200 1m;
add_header X-TEST $upstream_cache_status;
}

Но если попробовать создать отдельный локейшен для страницы контактов, то на выходе получаю 404 ошибку с No input file specified.


location /contact {
fastcgi_cache MYAPP;
fastcgi_cache_valid 200 1m;

include nginx.fastcgi.conf;
include nginx.redis.conf;
fastcgi_pass php_farm;
}

Если в этот локейшен добавить try_files $uri $uri/ /index.php?$query_string; то кэш не работает.

Подскажите, возможно ли как-то отдельно закешировать страницу контактов.

P.S. сама страница контактов для примера, т.к. задачей стоит кешировать на разное время ответы от backend по разным маршрутам.

M
На сайте с 17.09.2016
Offline
123
#1
T
На сайте с 11.08.2009
Offline
133
#2

В php можно, но все равно придется кэшировать весь бекэнд и далее обнулять кеш в php, но задача не в этом. Просто думаю неужели нельзя закешировать определенный get запрос по определенному адресу (что бы запрос не долетел до бэкенда)?

M
На сайте с 17.09.2016
Offline
123
#3

Telebird, Вы ссылку то откройте

Кешированием nginx можно управлять с помощью заголовков прямо в php


Поле заголовка “X-Accel-Expires” задаёт время кэширования ответа в секундах. Значение 0 запрещает кэшировать ответ. Если значение начинается с префикса @, оно задаёт абсолютное время в секундах с начала эпохи, до которого ответ может быть закэширован.
Если в заголовке нет поля “X-Accel-Expires”, параметры кэширования определяются по полям заголовка “Expires” или “Cache-Control”.
Ответ, в заголовке которого есть поле “Set-Cookie”, не будет кэшироваться.
Ответ, в заголовке которого есть поле “Vary” со специальным значением “*”, не будет кэшироваться (1.7.7). Ответ, в заголовке которого есть поле “Vary” с другим значением, будет закэширован с учётом соответствующих полей заголовка запроса (1.7.7).
T
На сайте с 11.08.2009
Offline
133
#4
Mobiaaa:
Telebird, Вы ссылку то откройте
Кешированием nginx можно управлять с помощью заголовков прямо в php

Возможно я плохо поставил вопрос. Попробую еще раз уточнить.

Мне НЕ нужно управлять кешем nginx из php, задача закешировать определенный Get запрос к бэкенду средствами Nginx и что-бы кеш стал не актуальным через минуту средствами Nginx. Уточню, сделать это только средствами nginx без Php, Varnish и т.д. То есть прямо в конфиге самого Nginx. Это нужно из за того, что базу модифицируют несколько приложений и когда какое из них ее изменит не определить. Необходимо просто что-бы кеш автоматом протухал.

M
На сайте с 17.09.2016
Offline
123
#5

Telebird, Возможно Вы неверно растолковали доку nginx

При передаче заголовка на кеширование через php - запрос один раз попадёт к бекенду, а дальше будет отдавать nginx кешированный запрос, ровно столько, сколько было указано в заголовке через php

Вариант с php гибче и проще реализовать

=========

в конфиге nginx я вижу пока один вариант, это создавать map

И добавлять все ссылки

При этом для каждого времени кеширования (час/сутки/неделю и т.д.) нужно будет добавлять новые map

map $request_uri $cache_hour {

"/contact" "1";

"/url2" "1";

}

и т.д.

=========

Как по мне, - проще в php динамически управлять временем кеширования, хоть от фазы луны

Нагрузки от этого никакой, так как в любом случае первый запрос будет идти к бекенду, и разницы особой нет - будет управление кешем в nginx или в php

Но гибкость - на лицо

T
На сайте с 11.08.2009
Offline
133
#6
Mobiaaa:
При передаче заголовка на кеширование через php - запрос один раз попадёт к бекенду, а дальше будет отдавать nginx кешированный запрос, ровно столько, сколько было указано в заголовке через php
Вариант с php гибче и проще реализовать

В конечном варианте нужно кэшировать весь бекенд а сбрасывать кэш через хидер по PHP?

Или не кешировать ничего, но для создания кеша использовать X-Accel-Expires?

В nginx у меня знаний маловато :(

В любом случае благодарю за ответ. Попробую реализовать с X-Accel-Expires

M
На сайте с 17.09.2016
Offline
123
#7

Telebird, header("X-Accel-Expires: 0");//

0 - не кешируем, больше 0 - кешируем на N сек

T
На сайте с 11.08.2009
Offline
133
#8
Mobiaaa:
Telebird, header("X-Accel-Expires: 0");//
0 - не кешируем, больше 0 - кешируем на N сек

Благодарю! Тоже возьму на вооружение.

Кстати все-же по своему вопросу тоже решил. Для выборочного кэширования можно использовать fastcgi_cache_bypass $cache; Переменную можно менять сверяя по $uri и все отлично работает 🍿

M
На сайте с 17.09.2016
Offline
123
#9

Telebird, Этот вариант я выше давал с Map'om

Но, как мне кажется, эту задачу лучше решать средствами php

куда практичнее, чем создавать 10/100/1000 правил для выборки кешировать/не кешировать

T
На сайте с 11.08.2009
Offline
133
#10
Mobiaaa:
Telebird, Этот вариант я выше давал с Map'om

Да вариант с map отлично отработал! Попробую воспользоваться Вашим советом и переделать на X-Accel-Expires в хидере ☝

12

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