Nginx кеширование, помогите настроить исключение

SeoPerez
На сайте с 11.07.2010
Offline
83
3466

Всем привет!

Неделю промаялся с настройкой NGINX кеширования на своем сервере для DLE сайта. Вроде наконец все получилось, но теперь появилась задача с которой я никак не могу справиться. Подскажите, пожалуйста, кто разбирается.

Необходимо добавить правило-исключение для последних добавленных на сайт новостей (чтобы они не кешировались). Адреса страниц имеют структуру: http://site.ru/99999-nazvanie-novosti.html , нужно добавить в исключения все новости у которых id больше 9999 (т.е. содержит 5 цифр).

Вот сам конфиг:


server {
server_name site.com www.site.com;
listen xxx.xxx.xxx.xxx;
set $root_path /var/www/site/data/www/site.com;
proxy_temp_path /var/cache/nginx/site.com;
location @nocached {
proxy_pass http://xxx.xxx.xxx.xxx:81;
proxy_redirect http://xxx.xxx.xxx.xxx:81/ /;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
location / {
proxy_pass http://xxx.xxx.xxx.xxx:81;
proxy_redirect http://xxx.xxx.xxx.xxx:81 /;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
#здесь мы фильтруем наших залогиненых пользователей
if ($cookie_dle_user_id) { return 412; }
if ($cookie_dle_password) { return 412; }
if ($request_method = POST ) {
return 412;
}
error_page 412 = @nocached;
proxy_cache one;
proxy_cache_key "$request_method|$is_args|$host|$request_uri";
#proxy_hide_header "Set-Cookie";
proxy_ignore_headers "Cache-Control" "Expires" "Set-Cookie";
proxy_cache_valid 200 302 304 2m;
proxy_cache_valid 301 1h;
proxy_cache_valid 503 4s;
proxy_cache_valid any 1m;
proxy_cache_use_stale http_502 http_503 http_504;
}
location ~ (admin.php|index.php?action=logout) {
proxy_pass http://xxx.xxx.xxx.xxx:81;
proxy_redirect http://xxx.xxx.xxx.xxx:81/ /;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
location ~* ^.+\.(jpg|jpeg|gif|png|svg|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar)$ {
root /var/www/site/data/www/site.com;
expires 1y;
error_page 404 = @fallback;
}
location @fallback {
proxy_pass http://xxx.xxx.xxx.xxx:81;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
include /usr/local/ispmgr/etc/nginx.inc;
charset CP1251;
}

Всячески пытался изменить вот эту вот строчку:

location ~ (admin.php|index.php?action=logout) {

location ~ (admin.php|index.php?action=logout|[0-9]{5}) {

location ~ (admin.php|index.php?action=logout|[0-9]{5,}) {

location ~ (admin.php|index.php?action=logout|[0-9]{5}-.*\.html) {

Пробовал также добавлять такие строки в код:

location ~* [0-9]{5} {

error_page 412 = @fallback;

return 412;

}

Но по итогу либо ничего не меняется (в плане кеша), либо сервер вообще отказывается запускаться =(

Подскажите что не так? Как правильно добавить/сделать это исключение?

► Сайты / домены покупаю и продаю здесь » (http://www.telderi.ru/?pid=1c41bf)
D
На сайте с 28.06.2008
Offline
1114
#1

А какой в этом смысл? Хотите чтобы свежие новости быстрее индексировались? Ну так вы создали новость - зашли на страницу и она в кеше, что не так?

SeoPerez
На сайте с 11.07.2010
Offline
83
#2

Нужно чтобы к новым новостям учитывались просмотры. Зачем - это другой вопрос, но это нужно сделать из-за некой специфики работы сайта.

---------- Добавлено 14.02.2017 в 16:00 ----------

Может быть в код PHP нужно добавить чего нибудь чтобы не срабатывало кеширование? (такой вариант был бы даже лучше, из-за большей гибкости фильтрации - на будущее)

Пробовал так:

if($row['id'] > 10100) {

header("Expires: Thu, 19 Nov 1981 08:52:00 GMT");

header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");

header("Pragma: no-cache");

}

И так:

if($row['id'] > 10100) {

session_cache_limiter('private');

}

Не помогает =(

redeyer
На сайте с 27.01.2010
Offline
102
#3

Какую-то жуткую конструкцию вы наворотили с этим кэшем)

Теоретически вот это должно работать, если для админки работает исключение.

SeoPerez:
location ~ (admin.php|index.php?action=logout|[0-9]{5}) {

Я обычно кэширование прописываю гораздо проще. Что-то вроде такого:


set $no_cache 0;

if ($request_method = POST) {
set $no_cache 1;
}
if ($query_string != "") {
set $no_cache 1;
}


if ($request_uri ~* "/admin.php|/administrator|/feed/|sitemap(_index)?.xml|") {
set $no_cache 1;
}

if ($http_cookie ~* "dle_user_id|dle_password|dle_compl") {
set $no_cache 1;

proxy_cache one;
proxy_cache_min_uses 1;
proxy_cache_valid 200 301 302 304 1h;
proxy_cache_key $scheme$host$request_uri$request_method;
proxy_ignore_headers "Cache-Control" "Expires" "Set-Cookie";
proxy_cache_bypass $no_cache;
proxy_no_cache $no_cache;

Это удобней хотя бы просто потому, что можно подключить инклюдом на любое количество сайтов на серваке, c той же ISPmanager, например.

А как проверяете работу кэширования? Может дело не в конфигах, а в проверках?

Услуги сисадмина. Настройка и оптимизация VPS https://searchengines.guru/ru/forum/928318 . Поднятие своих прокси, восстановление сайтов из вебархива. Мой канал о хостингах https://t.me/hostingexpert
SeoPerez
На сайте с 11.07.2010
Offline
83
#4
redeyer:
Какую-то жуткую конструкцию вы наворотили с этим кэшем)

Собирал все по крупицам на разных просторах интернета, основную часть на хабре например. Но в целом, там в примерах конструкция была примерно такая.

redeyer:

Теоретически вот это должно работать, если для админки работает исключение.

В том то и дело что не работает =( Не помню точно, толи сервер не запускается с таким конфигом, толи кеширование не работает. Могу в принципе еще разок попробовать, но пробовал уже не раз и даже не два.

redeyer:
А как проверяете работу кэширования? Может дело не в конфигах, а в проверках?

Ну при залогиненом юзере, если делаю правки какие то в новостях, они при обновлении странички тут же применяются и отображаются. Если же делаю такие проверки под гостем, то изменений при обновлении не происходит.

Так вот, по логике, при добавлении такого исключения, при обновлении новостей с id>9999, все изменения должны отображаться сразу, даже для гостей. Но этого не происходит.

redeyer:
Я обычно кэширование прописываю гораздо проще. Что-то вроде такого:

set $no_cache 0;

if ($request_method = POST) {
set $no_cache 1;
}
if ($query_string != "") {
set $no_cache 1;
}


if ($request_uri ~* "/admin.php|/administrator|/feed/|sitemap(_index)?.xml|") {
set $no_cache 1;
}

if ($http_cookie ~* "dle_user_id|dle_password|dle_compl") {
set $no_cache 1;

proxy_cache one;
proxy_cache_min_uses 1;
proxy_cache_valid 200 301 302 304 1h;
proxy_cache_key $scheme$host$request_uri$request_method;
proxy_ignore_headers "Cache-Control" "Expires" "Set-Cookie";
proxy_cache_bypass $no_cache;
proxy_no_cache $no_cache;


Это удобней хотя бы просто потому, что можно подключить инклюдом на любое количество сайтов на серваке, c той же ISPmanager, например.

О, у меня как раз ISP. А что это за код? Полный конфиг для сайта или его часть?

---------- Добавлено 14.02.2017 в 22:11 ----------

Сейчас попробовал вот этот вариант еще раз:

location ~ (admin.php|index.php?action=logout|[0-9]{5}) {

По итогу сервер не включается с таким конфигом (все время 521 ошибка), пока не вернешь обратно. Точнее сервер включается и работает, и даже работают другие сайты размещенные на нем - но не тот сайт для которого написан этот конфиг.

redeyer
На сайте с 27.01.2010
Offline
102
#5
SeoPerez:
Ну при залогиненом юзере, если делаю правки какие то в новостях, они при обновлении странички тут же применяются и отображаются. Если же делаю такие проверки под гостем, то изменений при обновлении не происходит.

Можно добавить заголовок статуса кэширования, с ним гораздо проще делать отладку:


add_header X-Cache $upstream_cache_status;

после этого в заголовках страницы будет показывать:

SeoPerez:
А что это за код? Полный конфиг для сайта или его часть?

Это полный конфиг для добавления кэширования к любому сайту. Т.е если в контекст server его вставить или проинклудить - то должно нормально работать. Ну, зону поправить, если отличается. У меня она называется "one", у вас тоже.

SeoPerez:
Сейчас попробовал вот этот вариант еще раз:
location ~ (admin.php|index.php?action=logout|[0-9]{5}) {

Тут скорей всего дело в том, что регулярка без кавычек или скобок не работает. У меня uri проверяется через if, обычно работает

нормально. Попробуйте не в location ее дописать, а туда, где куки проверяете:


#здесь мы фильтруем наших залогиненых пользователей
if ($cookie_dle_user_id) { return 412; }
if ($cookie_dle_password) { return 412; }
if ($request_method = POST ) {
return 412;
}
if ($request_uri ~* "[0-9]{5}") {return 412;}

Что-то типа такого.

SeoPerez
На сайте с 11.07.2010
Offline
83
#6
redeyer:
Попробуйте не в location ее дописать, а туда, где куки проверяете:

#здесь мы фильтруем наших залогиненых пользователей
if ($cookie_dle_user_id) { return 412; }
if ($cookie_dle_password) { return 412; }
if ($request_method = POST ) {
return 412;
}
if ($request_uri ~* "[0-9]{5}") {return 412;}

Что-то типа такого.

Так сработало! ) Спасибо Вам огромное! ))

Теперь буду мозговать как в будущем корректировать эту регулярку, когда количество не кешируемых новостей перевалит за тысячу..

UPD: А не, все довольно легко решается =)

Например такой регуляркой, 10[2-9][0-9]{2}

redeyer
На сайте с 27.01.2010
Offline
102
#7
SeoPerez:
Так сработало! ) Спасибо Вам огромное! ))

Ну отлично, пожалуйста)

Но переписать конфиг на более простой и удобный всё же рекомендую.

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