Как сбросить кэш nginx
Как очистить кеш nginx?
Я использую nginx в качестве переднего сервера, я изменил файлы CSS, но nginx все еще обслуживает старые.
Я попытался перезапустить nginx, не добившись успеха, и у меня есть Googled, но не найден допустимый способ его очистки.
Что мне теперь делать?
ОТВЕТЫ
Ответ 1
Sendfile используется для «копирования данных между одним дескриптором файла и другим» и, по-видимому, имеет некоторые реальные проблемы при запуске в среде виртуальной машины или, по крайней мере, при запуске через Virtualbox. Отключение этой конфигурации в nginx приводит к тому, что статический файл обслуживается другим способом, и ваши изменения будут отражены немедленно и без вопросов
Ответ 2
Вы также можете обходить/повторно кэшировать файл по файлу, используя
и в качестве бонуса вы можете вернуть этот заголовок, чтобы узнать, достали ли вы его из кеша (вернете «HIT» ) или с сервера содержимого (вернете «BYPASS» ).
для истечения/обновления кэшированного файла, используйте curl или любой клиент для отдыха, чтобы сделать запрос на кэшированную страницу.
это вернет новую копию элемента, а также заменит то, что в кеше.
Ответ 3
Если вы это сделали, то в соответствии с автором nginx достаточно просто удалить все файлы из каталога кеша.
Ответ 4
Вы можете удалить каталог кеширования nginx или выполнить поиск определенного файла:
И удалите только один файл, чтобы обновить nginx.
Ответ 5
В этом вопросе есть два ответа.
Ответ 6
В моей установке nginx я обнаружил, что мне нужно перейти к:
Ответ 7
Я нашел это полезным
Поиск, а если он найден, удалите.
Ответ 8
У меня тоже была эта проблема.
Мой домен использует cloudflare.com для DNS (отличный сервис!). Ага! Там было:
cloudflare.com → кеширование → Очистить кеш (я очистил все) Это решило мою проблему!
Ответ 9
Я запускаю очень простой bash script, который занимает все 10 секунд, чтобы выполнить задание, и отправляет мне почту по завершении.
Ответ 10
У нас очень большой кеш nginx (гигабайт), который нам иногда нужно стереть. Я разработал script, который мгновенно очищает кеш (насколько это касается Nginx), а затем удаляет каталог кеша без голодания основного приложения для ввода/вывода диска.
Здесь script, с учетом Ubuntu 16.04 LTS, с кешем, расположенным в /mnt/nginx-cache :
И в случае, если это полезно, здесь используется конфигурация Nginx:
Ответ 11
Для тех, у кого другие решения не работают, проверьте, используете ли вы службу DNS, такую как CloudFlare. В этом случае активируйте «Режим разработки» или используйте инструмент «Очистить кэш».
Ответ 12
Обратите внимание, что proxy_cache_bypass может дать вам мир обид, если ваше приложение не вернет кэш-ответ для этого конкретного запроса, где вы его вызываете.
Если, например, ваше приложение отправляет cookie с каждым первым запросом, то script, который запускает proxy_pass_bypass через curl, вероятно, получит этот файл cookie в ответе, а nginx не будет использовать этот ответ для обновления кэшированного элемента.
Ответ 13
Соблюдайте правильную настройку правильного пути.
Ответ 14
Для тех, кто пытался удалить файлы кеша nginx, и либо он не работал, либо работал с перерывами, посмотрите на свой параметр для open_file_cache. Если это включено и настроено для кэширования файлового дескриптора в течение длительного времени, Nginx все еще может видеть версию кэшированного файла даже после того, как вы удалили его с диска. Мне пришлось уменьшить open_file_cache_valid до 1s (я не уверен, что это по сути то же самое, что полностью отключить кеш файл).
Ответ 15
Теперь, если вы хотите обойти кеш, вы получите доступ к файлу, передав параметр nocache
Ответ 16
На моем сервере папка кеша nginx находится в /data/nginx/cache/
Надеюсь, это поможет любому.
Ответ 17
Вы можете добавить конфигурацию в nginx.conf, как показано ниже.
Сверху динамически создается папка с именем «nginx_cache» в/tmp/для хранения кэшированного содержимого.
Ответ 18
Существует один правильный метод удаления только кеш файлов, который соответствует любому KEY. Например:
Это удаляет все файлы кэша, которые соответствуют KEY «yahoo/*», если в nginx.conf установлен:
Ответ 19
У меня возникла подобная проблема:
Решение: В VM найдите общий файл (файл css в моем случае). Открыть с nano и сравнить с файлом в share Windows (они кажутся идентичными). На виртуальной машине сохранить общий файл с помощью nano. Все изменения теперь отображаются в браузере. Не уверен, почему это работает, но это произошло в моем случае.
UPDATE: после перезагрузки сервера VM проблема вернулась. Следуя инструкциям в разделе «Решение», css снова реагирует на обновления.
Ответ 20
В моем случае это был включенный opcache в /etc/php/7.2/fpm/php.ini(Ubuntu):
При установке значения 0 сервер загружал последнюю версию (php) файлов.
Ответ 21
Мы используем nginx для кеширования множества вещей. В каталоге кеша находятся десятки тысяч элементов. Чтобы найти элементы и удалить их, мы разработали несколько скриптов для упрощения этого процесса. Вы можете найти репозиторий для этих скриптов ниже:
Идея проста. Создать индекс кэша (с ключами кэша и соответствующими файлами кэша) и выполнить поиск в этом файле индекса. Это действительно помогло нам ускорить поиск элементов (с минут до секунды) и соответственно удалить их.
Кэширование ответа от backend с помощью NGINX
Для FastCGI кэш задается с помощью опций fastcgi_cache_*. Для запросов к бэкэнду с помощью proxy_pass — proxy_cache_*.
Рекомендации и противопоказания
Кэш — это данные не первой свежести. Это важно учитывать, если мы хотим настроить эффективное кэширование средствами nginx. Мы можем столкнуться с различными проблемами, например, неспособность сервера продлить сессию авторизованного пользователя или отображение старой информации на портале с динамично меняющимся контентом. Чтобы избежать данных проблем, настройка nginx должна быть тесно сопряжена с разработкой сайта. Идеальная работа кэша возможна только при полном понимании внутренних механизмах работы портала, такие как, отправка запросов на авторизацию, продление сессии, обновлении контента — программист может написать для этого запрос по определенным URL, для которого администратор NGINX может отключить кэширование.
Кэширование динамики будет полезно для сайтов с высокой посещаемостью, из-за которой создается высокая нагрузка на сервер и он не может успеть выполнить обработку запросов. Также оно будет полезно для отдельных страниц, содержимое которых меняется очень редко, но отработка скриптов выполняется долго.
Из всего этого можно сделать вывод, что кэширование на стороне сервера NGINX стоит применять только в случае высоких нагрузок и медленной работы сайта из-за долгой работы backend’а.
Настройка кэширования для proxy_pass
Как было сказано выше, для разных методов обращения к серверу, который обрабатывает запрос, нужно использовать разные методы кэширования.
Включение кэширования
Открываем конфигурационный файл nginx:
В секцию http добавляем:
http <
.
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=all:64m inactive=2h max_size=2g;
.
>
* в данном примере мы задали глобальную настройку для кэширования:
Создаем каталог для хранения кэша и задаем владельца:
chown nginx:nginx /var/cache/nginx
Настройка хостов
Чтобы определенный сайт или отдельная страница кешировала запрос, открываем конфигурационный файл с настройками виртуального домена или хоста, например:
. и добавим к proxy_pass кэширование — мы получим что-то на подобие:
location / <
if ($http_cookie
Применение настроек
NGINX настроен. Проверим корректность настроек:
Если ошибок нет, применяем их:
systemctl restart nginx
Теперь заходим на сайт и смотрим в каталог с кэшем — в нем должны появиться каталоги и файлы:
Мы должны увидеть что-то на подобие:
drwx——. 3 nginx nginx 4096 Jan 25 16:09 0
drwx——. 5 nginx nginx 4096 Jan 25 16:09 2
drwx——. 5 nginx nginx 4096 Jan 25 16:15 3
drwx——. 3 nginx nginx 4096 Jan 25 16:09 4
drwx——. 4 nginx nginx 4096 Jan 26 05:08 5
drwx——. 3 nginx nginx 4096 Jan 25 16:09 6
drwx——. 3 nginx nginx 4096 Jan 26 04:18 7
drwx——. 3 nginx nginx 4096 Jan 25 16:10 8
drwx——. 5 nginx nginx 4096 Jan 25 16:15 a
drwx——. 3 nginx nginx 4096 Jan 25 16:09 b
drwx——. 5 nginx nginx 4096 Jan 26 04:19 e
drwx——. 3 nginx nginx 4096 Jan 25 19:55 f
Настройка кэширования для fastcgi_pass
Настройка fastcgi_cache аналогична proxy_cache и настройки можно сделать по подобию последнего, заменив proxy_ на fastcgi_. Мы разберем основные настройки без подробностей и комментариев.
Открываем конфиг nginx:
Добавляем в секцию http:
http <
.
fastcgi_cache_path /var/cache/fastcgi levels=1:2 keys_zone=fastcgi:64m inactive=2h max_size=2g;
.
>
* обратите внимание, что мы задали другой каталог и keys_zone.
Создаем каталог для кэша:
chown nginx:nginx /var/cache/fastcgi
location / <
if ($http_cookie
Проверяем настройки и применяем их:
systemctl restart nginx
Кэширование статики
Кэширование статики не имеет никакого отношения к кэшированию ответа от бэкэнда, однако, это тоже позволяет разгрузить сервер. Суть в том, что nginx сам умеет отдавать статические файлы + задавать инструкцию для браузера по ее кэшированию.
Настройка выполняется для каждого виртуального хоста (секция server):
* ^.+\.(css|js)$ <
root /var/www/site
expires modified +1w;
>
location
* в данном примере мы задаем для файлов изображений (jpg, jpeg, gif, png) кэш до 31 декабря 2037 23:55:55 (max), для файлов css и js — 1 неделя с момента их модификации. Данные настройки мы задаем при помощи параметра expires, который, в свою очередь, задает заголовок cache-control. NGINX будет искать статические файлы в корневом каталоге /var/www/site.
После применяем настройки:
systemctl restart nginx
Отключение кэширования
Как говорилось выше, в некоторых случаях, кэширование может навредить и на некоторых страницах его стоит отключить. В настройках виртуального хоста, мы можем создать отдельный location, для которого отключиться кэш, например:
location /proxy_nocache <
proxy_pass http://localhost:3000;
.
proxy_cache off;
>
location /fastcgi_nocache <
fastcgi_pass http://localhost:9000;
.
fastcgi_cache off;
>
* обратите внимание, что в данном примере мы отключаем кэширование как для запросов proxy_pass, так и fastcgi_pass.
При отключении кэширования для статики используем следующую конфигурацию:
* ^.+\.(jpg|jpeg|gif|png|css|js)$ <
root /var/www/site
expires epoch;
>
>
* expires epoch задаст заголовок сache-control с временем окончания кэша «1 января 1970 00:00:01».
Сброс кэша
Удалить кэш на стороне сервера nginx мы можем только для бэкэнда. Для статики нужно удалять кэш в самом браузере (например, в настройках или с помощью дополнений).
Для сброса кэша мы просто должны удалить содержимое каталога, который прописан в опции proxy_cache_path или fastcgi_cache_path — в нашем случае, это /var/cache/nginx и /var/cache/fastcgi соответственно.
а) для proxy_cache_path:
б) для fastcgi_cache_path:
Хранение кэша в оперативной памяти
Мы можем значительно ускорить процесс записи и чтения информации, если будем хранить кэш в оперативной памяти.
Создаем обычный каталог, в который будем монтировать часть оперативной памяти:
. и дадим на него полные права:
chmod 777 /var/ramdisk
Монтируем часть оперативной памяти как обычный каталог:
* в данном примере мы монтируем 2 Гб оперативной памяти как папку /var/ramdisk. Возможно, правильнее будет заранее убедиться в наличие свободной памяти командой free.
Для автоматического монтирования открываем на редактирование fstab:
ramdisk /var/ramdisk tmpfs nodev,nosuid,noexec,nodiratime,size=2G 0 0
Теперь, когда у нас есть каталог, данные которого хранятся в оперативной памяти, редактируем параметр proxy_cache_path или fastcgi_cache_path в NGINX:
proxy_cache_path /var/ramdisk levels=1:2 keys_zone=all:64m inactive=2h max_size=2g;
fastcgi_cache_path /var/ramdisk levels=1:2 keys_zone=fastcgi:64m inactive=2h max_size=2g;
Как очистить кеш nginx?
Я использую nginx в качестве переднего сервера, я изменил файлы CSS, но nginx по-прежнему обслуживает старые.
Я попытался перезапустить nginx, но безуспешно, и я погуглил, но не нашел действительного способа его очистить.
Что мне теперь делать?
24 ответа
Sendfile используется для «копирования данных между одним файловым дескриптором и другим» и, по-видимому, имеет некоторые реальные проблемы при запуске в среде виртуальной машины или, по крайней мере, при запуске через Virtualbox. Отключение этой конфигурации в nginx приводит к тому, что статический файл будет обслуживаться другим методом, и ваши изменения будут отражены немедленно и без вопросов.
В моем случае это был включенный opcache в /etc/php/7.2/fpm/php.ini (Ubuntu):
Установка его на 0 заставила сервер загружать последнюю версию файлов (php).
Уже есть много ответов, но я думаю, что у меня есть полезное дополнение;
Я запускаю систему Homestead с Hyper-V, и у меня есть проект laravel, работающий на nginx.
У меня не было кеша в моей папке nginx в / etc /
Когда я посещал свой веб-сайт, я получал старые представления сервера и файлы css.
Что решило это для меня после поиска, потраченного впустую, глядя на мою конфигурацию nginx и пробуя вещи, было использование PHP artisan.
Выполните следующую команду в папке, где установлен artisan [корневой каталог проекта laravel]: php artisan optimize: clear
Эта команда очищает все кеши, и когда я обновил свою веб-страницу, она наконец обновилась со всеми изменениями.
Надеюсь, это поможет таким заблудшим душам, как я 🙂
Как и StackOverflow. 🙂
У меня была похожая проблема:
Решение: На виртуальной машине найдите общий файл (в моем случае файл css). Откройте с помощью nano и сравните с файлом в общей папке Windows (они кажутся идентичными). На виртуальной машине сохраните общий файл с помощью nano. Все изменения теперь отображаются в браузере. Не уверен, почему это работает, но в моем случае так оно и было.
ОБНОВЛЕНИЕ: после перезагрузки сервера ВМ проблема вернулась. Следуя инструкциям в разделе «Решение», CSS снова стал реагировать на обновления.
Мы используем nginx для кеширования большого количества вещей. В каталоге кеша находятся десятки тысяч элементов. Чтобы найти элементы и удалить их, мы разработали несколько сценариев, упрощающих этот процесс. Вы можете найти ссылку на репозиторий кода, содержащий эти скрипты, ниже:
Идея проста. Чтобы создать индекс кеша (с ключами кеша и соответствующими файлами кеша) и выполнить поиск в этом индексном файле. Это действительно помогло нам ускорить поиск элементов (с минут до долей секунды) и соответственно удалить их.
В моем случае, touch этот файл Css, чтобы он выглядел так, как будто ресурсы были изменены (на самом деле touch ничего не делает с файлом, кроме изменения времени последнего изменения), поэтому браузер и nginx будут применять последние ресурсы
Вы можете добавить конфигурацию в nginx.conf следующим образом.
Сверху папка с именем «nginx_cache» динамически создается в / tmp / для хранения кэшированного содержимого.
Теперь, если вы хотите обойти кеш, вы обращаетесь к файлу, передавая параметр nocache
Есть один правильный способ удалить только кеш-файлы, соответствующие любому KEY. Например:
Это удаляет все кеш-файлы, соответствующие КЛЮЧУ «yahoo / *», если в nginx.conf был установлен:
Будьте внимательны, чтобы правильно указать правильный путь.
На моем сервере папка кеша nginx находится по адресу /data/nginx/cache/
Надеюсь, это кому-нибудь поможет.
Для тех, кто пытался удалить файлы кеша nginx, но он либо не работал, либо работал с перерывами, обратите внимание на ваши настройки для open_file_cache. Если это включено и настроено для кеширования файлового дескриптора в течение длительного времени, Nginx может по-прежнему видеть версию кэшированного файла даже после того, как вы удалили его с диска. Мне пришлось уменьшить open_file_cache_valid до 1 с (я не уверен, что это по сути то же самое, что полностью отключить кеш файлов).
Обратите внимание, что proxy_cache_bypass может причинить вам серьезную боль, если ваше приложение не возвращает кешируемый ответ для того конкретного запроса, в котором вы его запускаете.
Если, например, ваше приложение отправляет файл cookie с каждым первым запросом, то сценарий, который запускает proxy_pass_bypass через curl, вероятно, получит этот файл cookie в ответ, а nginx не будет использовать этот ответ для обновления кешированного элемента.
Тем, у кого другие решения не работают, проверьте, используете ли вы службу DNS, например CloudFlare. В этом случае активируйте «Режим разработки» или используйте инструмент «Очистить кэш».
У нас очень большой кеш nginx (гигабайты), который нам иногда нужно очистить. Я разработал сценарий, который мгновенно очищает кеш (что касается Nginx), а затем удаляет каталог кеша, не ограничивая основное приложение дисковым вводом-выводом.
Вот сценарий, адаптированный для Ubuntu 16.04 LTS, с кешем, расположенным в /mnt/nginx-cache :
И в случае, если это будет полезно, вот конфигурация Nginx, которую мы используем:
В моей установке nginx я обнаружил, что мне нужно перейти к:
У меня тоже была эта проблема.
В моем домене в качестве DNS используется cloudflare.com (отличный сервис!). Ага! Вот это было:
Я нашел это полезным
Ищи, а если найдешь то удаляй.
Я запускаю очень простой сценарий bash, который выполняет задание за 10 секунд и отправляет мне письмо по завершении.
На этот вопрос есть два ответа.
Вы можете удалить каталог кеша nginx или выполнить поиск в конкретном файле:
И удалите только один файл, чтобы nginx обновил их.
Однако если вы это сделали, то в соответствии с автор nginx, достаточно просто удалить все файлы из каталога кеша.
Вы также можете обходить / повторно кешировать файл за файлом, используя
И в качестве бонуса вы можете вернуть этот заголовок, чтобы узнать, получили ли вы его из кеша (вернет «HIT») или с сервера содержимого (вернет «BYPASS»).
Для истечения срока действия / обновления кэшированного файла используйте curl или любой другой клиент для выполнения запроса к кэшированной странице.
Это вернет новую копию элемента, а также заменит то, что находится в кеше.
В процессе работ по шареду нашел проблему в nginx (не чистится клиентский кэш)
Ниже приведет алгоритм моих действий и результат.
Удаляем кеш клиентов nginx за последние 7 дней
Уменьшаем размер кеша под nginx
Уменьшить желательно до max_size=50m;
Иначе, исходя из ситуации, которую я наблюдал в процессе очистки завирусованных файлов пользовательского кэша, автоочистка работать корректно не будет.
50m вполне достаточно для нормальной работы кэширования. Слишком большой размер кэша приводит к накоплению большого количества файлов кэша и повышенный iowait от постоянного перебора этих файлов в nginx.
Кроме этого в настройках кэширования не было параметра inactive, это и привело к основной проблеме, поскольку файлы не чистились и тот 1 ГБ, который был выделен, сейчас забит пустыми файлами, которые занимают айноды и приводят к тому, что nginx ищет активный кэш очень долго.
После очистки и настройки параметра inactive кэш начнет работать эффективнее.
Применил правило удаления неактивного кэша, к которому не было запросов больше 7 дней. Секция кэширования теперь выглядит так:
После проверки через неделю заметил, что nginx самостоятельно не удаляет все файлы неактивного кэша. Сегодня проверил, как минимум вижу, что к некоторым файлам не было запросов больше 10 дней.
Во первых командой было замечено что директория кэша превышает максимальный разрешенный объем
Во вторых в директории есть файлы, доступ к которым запрашивался больше 7 дней назад
И проблема в нагрузке на сервер не только в самом nginx, а например, в тех же clamav, locate и т.д., которые периодически перебирают/сканируют эти файлы и тем самым из-за большого их количесва отрабатывают «тяжело и медленно».
Чтобы это все не накапливалось, поставил задание в крон, чтобы ежедневно удалялись неактивные файлы кэша, к которым не было запросов больше 7 дней
После очистки по крону, проблема решилась и больше кеш не скапливается лишний.
Nginx cache: всё новое — хорошо забытое старое
В жизни каждого проекта настает время, когда сервер перестает отвечать требованиям SLA и буквально начинает захлебываться количеством пришедшего трафика. После чего начинается долгий процесс поиска узких мест, тяжелых запросов, неправильно созданных индексов, не кэшированных данных, либо наоборот, слишком часто обновляемых данных в кэше и других темных сторон проекта.
Но что делать, когда ваш код “идеален”, все тяжелые запросы вынесены в фон, все, что можно, было закэшировано, а сервер все так же не дотягивает до нужных нам показателей SLA? Если есть возможность, то конечно можно докупить новых машин, распределить часть трафика и забыть о проблеме еще на некоторое время.
Но если вас не покидает чувство, что ваш сервер способен на большее, или есть магический параметр, ускоряющий работу сайта в 100 раз, то можно вспомнить о встроенной возможности nginx, позволяющей кэшировать ответы от бэкенда. Давайте разберем по порядку, что это, и как это может помочь увеличить количество обрабатываемых запросов сервером.
Что такое Nginx cache и как он работает?
Nginx кэш позволяет значительно сократить количество запросов на бэкенд. Это достигается путем сохранения HTTP ответа, на определенное время, а при повторном обращении к ресурсу, отдачи его из кэша без проксирования запроса на бекенд. Кэширование, даже на непродолжительный период, даст значительный прирост к количеству обрабатываемых запросов сервером.
Перед тем как приступить к конфигурации nginx, необходимо убедиться, что он собран с модулем “ngx_http_proxy_module”, так как с помощью этого модуля мы и будем производить настройку.
Для удобства можно вынести конфигурацию в отдельный файл, например “/etc/nginx/conf.d/cache.conf”. Давайте рассмотрим директиву “proxy_cache_path”, которая позволяет настроить параметры хранения кэша.
“/var/lib/nginx/proxy_cache” указывает путь хранения кэша на сервере. Именно в эту директорию nginx будет сохранять те самые файлы с ответом от бэкенда. При этом nginx не будет самостоятельно создавать директорию под кэш, об этом необходимо позаботиться самому.
“levels=1:2” — задает уровень вложенности директорий с кэшем. Уровни вложенности указываются через “:”, в данном случае будет созданы 2 директории, всего допустимо 3 уровня вложенности. Для каждого уровня вложенности доступны значения от 1 до 2, указывающие, как формировать имя директории.
Важным моментом является то, что имя директории выбирается не рандомно, а создается на основе имени файла. Имя файла в свою очередь является результатом функции md5 от ключа кэша, ключ кэша мы рассмотрим чуть позже.
Давайте посмотрим на практике, как строится путь до файла кэша:
“keys_zone=proxy_cache:15m” параметр задает имя зоны в разделяемой памяти, где хранятся все активные ключи и информация по ним. Через “:” указывается размер выделяемой памяти в Мб. Как заявляет nginx, 1 Мб достаточно для хранения 8 тыс. ключей.
“max_size=1G” определяет максимальный размер кэша для всех страниц, при превышении которого nginx сам позаботится об удалении менее востребованных данных.
Также есть возможность управлять временем жизни данных в кэше, для этого достаточно определить параметр “inactive” директивы “proxy_cache_path”, который по умолчанию равен 10 минутам. Если в течение заданного в параметре “inactive” времени к данным кэша не было обращений, то эти данные удаляются, даже если кэш еще не “скис”.
Что же из себя представляет этот кэш? На самом деле это обычный файл на сервере, в содержимое которого записывается:
• ключ кэша;
• заголовки кэша;
• содержимое ответ от бэкенда.
Если с заголовками и ответом от бэкенда все понятно, то к “ключу кэша” есть ряд вопросов. Как он строится и как им можно управлять?
Для описания шаблона построения ключа кэша в nginx существует директива “proxy_cache_key”, в которой в качестве параметра указывается строка. Строка может состоять из любых переменных, доступных в nginx.
Символ “:” между параметром куки и get-параметром используется для предотвращения коллизий между ключами кэша, вы можете выбрать любой другой символ на ваше усмотрение. По умолчанию nginx использует следующую строку для формирования ключа:
Следует отметить следующие директивы, которые помогут более гибко управлять кэшированием:
proxy_cache_valid — Задает время кэширования ответа. Возможно указать конкретный статус ответа, например 200, 302, 404 и т.д., либо указать сразу все, с помощью конструкции “any”. В случае указания только времени кэширования, nginx по дефолту будет кэшировать только 200, 301 и 302 статусы.
В этом примере мы установили время жизни кэша в 15 минут, для статусов 200, 301, 302 (их nginx использует по умолчанию, так как мы не указали конкретный статус). Следующей строчкой установили время кэширования в 15 секунд, только для ответов со статусом 404.
proxy_cache_lock — Эта директива поможет избежать сразу нескольких проходов на бэкенд за набором кэша, достаточно установить значение в положении “on”. Все остальные запросы будут ожидать появления ответа в кэше, либо таймаут блокировки запроса к странице. Соответственно, все таймауты возможно настроить.
proxy_cache_lock_age — Позволяет установить лимит времени ожидания ответа от сервера, после чего на него будет отправлен следующий запрос за набором кэша. По умолчанию равен 5 секундам.
proxy_cache_lock_timeout — Задает время ожидания блокировки, после чего запрос будет передан на бэкенд, но ответ не будет закэширован. По умолчанию равен 5 секундам.
proxy_cache_use_stale — Еще одна полезная директива, позволяющая настроить, при каких случаях возможно использовать устаревший кэш.
В данном случае будет использовать устаревший кэш в случае ошибки подключения, передачи запроса, чтения ответа с сервера, превышения лимита ожидания отправки запроса, чтения ответа от сервера, либо если в момент запроса происходит обновление данных в кэше.
proxy_cache_bypass — Задает условия, при которых nginx не станет брать ответ из кэша, а сразу перенаправит запрос на бэкенд. Если хотя бы один из параметров не пустой и не равен “0”. Пример:
proxy_no_cache — Задает условие при котором nginx не станет сохранять ответ от бэкенда в кэш. Принцип работы такой же как у директивы “proxy_cache_bypass”.
Возможные проблемы при кэшировании страниц
Как уже упоминалось выше, вместе с кешированием HTTP ответа nginx сохраняет полученные от бэкенда заголовки. Если на вашем сайте используется сессия, то сессионная кука также будет закэширована. Все пользователи, зашедшие на страницу, которую вам посчастливилось закэшировать, получат ваши персональные данные, хранящиеся в сессии.
Следующая задача, с которой придется столкнуться — это управление кэшированием. Конечно можно установить незначительное время кэша в 2-5 минут и этого будет достаточно в большинстве случаев. Но не во всех ситуациях такое применимо, поэтому будем изобретать свой велосипед. Теперь обо всем по порядку.
Управление сохранением cookie
Кэширование на стороне nginx накладывает некоторые ограничения на разработку. Например, мы не можем использовать сессии на закэшированных страницах, так как пользователь не доходит до бэкенда, еще одним ограничением будет отдача cookies бэкендом. Так как nginx кэширует все заголовки, то чтобы избежать сохранения чужой сессии в кэше, нам нужно запретить отдачу cookies для кэшируемых страниц. В этом нам поможет директива “proxy_ignore_headers”. В качестве аргумента перечисляются заголовки, которые должны быть игнорированы от бэкенда.
Этой строкой мы игнорируем установку cookies с проксируемого сервера, то есть пользователь получит ответ без заголовка “Set-Cookies”. Соответственно все, что бэкенд попытался записать в cookie, будет проигнорировано на стороне клиента, так как он даже не узнает, что ему что-то предназначалось. Это ограничение в установке cookie следует учесть при разработке приложения. Например для запроса авторизации можно отключить игнорирование заголовка, чтобы пользователь получил сессионную куку.
Также следует учитывать время жизни сессии, его можно посмотреть в параметре “session.gc_maxlifetime” конфига php.ini. Представим, что пользователь авторизовался на сайте и приступил к просмотру новостной ленты, все данные при этом уже есть в nginx кэше. Через некоторое время пользователь замечает, что его авторизация пропала и ему снова нужно проходить процесс авторизации, хотя все это время он находился на сайте, просматривая новости. Это произошло потому, что на все его запросы nginx отдавал результат из кэша, не передавая запрос на бэкенд. Поэтому бэкенд решил, что пользователь неактивен и спустя время указанное в “session.gc_maxlifetime” удалил файл сессии.
Чтобы этого не происходило, мы можем эмулировать запросы на бэкенд. Например через ajax посылать запрос, который будет гарантированно проходить на бэкенд. Чтобы пройти на бэкенд мимо nginx кэша, достаточно отправить POST запрос, также можно использовать правило из директивы “proxy_cache_bypass”, либо просто отключить кэш для этой страницы. Запрос не обязательно должен что-то отдавать, это может быть файл с единственной строкой, стартующей сессию. Цель такого запроса — продлить время жизни сессии, пока пользователь находится на сайте, и на всего его запросы nginx добросовестно отдает закэшированные данные.
Управление сбросом кэша
Вначале необходимо определиться с требованиями, какую цель мы пытаемся достигнуть. Допустим, на нашем сайте есть раздел с текстовой трансляцией популярных спортивных событий. При загрузке страница отдается из кэша, дальше все новые сообщения приходят по сокетам. Для того, чтобы при первой загрузке пользователь видел актуальные сообщения на текущее время, а не 15 минутной давности, нам необходимо иметь возможность самостоятельно сбрасывать кэш nginx в любой момент времени. При этом nginx может быть расположен не на той же машине, что и приложение. Также одним из требований к сбросу будет возможность удаления кэша, сразу по нескольким страницам за раз.
Перед тем как начать писать свое решение, посмотрим, что предлагает nginx из “коробки”. Для сброса кэша в nginx предусмотрена специальная директива “proxy_cache_purge”, в которой записывается условие сброса кэша. Условие на самом деле является обычной строкой, которая при непустом и не “0” значении удалит кэш по переданному ключу. Рассмотрим небольшой пример.
Пример взят с официального сайта nginx.
Мы знаем, что nginx кэш — это обычный файл на сервере. Директорию для хранения файлов кэша мы самостоятельно указали в директиве “proxy_cache_path”, даже логику формирования пути до файла от этой директории мы указали с помощью “levels”. Единственное, чего нам не хватает, это правильного формирования ключа кэширования. Но и его мы можем подсмотреть в директиве “proxy_cache_key”. Теперь все что нам остается сделать это:
Шаг 1. Формирование файла с путями до кэша.
Обратите внимание, что в переменной “$urls” содержатся url закэшированных страниц, уже в формате “proxy_cache_key”, указанном в конфиге nginx. Url выступает неким тегом для выводимых сущностей на странице. Например, можно создать обычную таблицу в бд, где каждый сущности будет сопоставлена конкретная страница, на которой она выводится. Тогда при изменении каких-либо данных мы можем сделать выборку по таблице и удалить кэш всех необходимых нам страниц.
Шаг 2. Подключение на кэширующий сервер и удаление файлов кэша.
Приведенные примеры несут ознакомительный характер, не стоит использовать их в production. В примерах опущены проверки входных параметров и ограничения команд. Одна из проблем с которой можно столкнутся — это ограничение длины аргумента команды “rm”. При тестировании в dev окружении на небольших объемах это можно легко упустить, а в production получить ошибку “rm: Argument list too long”.
Кэширование персонализированных блоков
Давайте подведем итог, что нам удалось сделать:
Нужно рассмотреть альтернативную подгрузку таких частей страницы. Как всегда это можно сделать множеством способов, например после загрузки страницы отправлять ajax запрос, а на месте персонального контента отображать лоадер. Другим способом, который мы как раз сегодня и рассмотрим, будет использование ssi тегов. Давайте вначале разберемся что из себя представляет SSI, а затем, как мы можем его использовать в связке с nginx кэшем.
Что такое SSI и как он работает
SSI (Server-Side Includes, включения на стороне сервера) — это некий набор команд, встраиваемых в html страницу, указывающие серверу, что нужно сделать.
Вот некоторый перечень таких команд (директив):
• if/elif/else/endif — Оператор ветвления;
• echo — Выводит значения переменных;
• include — Позволяет вставлять содержимое другого файла в документ.
Как раз о последней директиве и пойдет речь. Директива include имеет два параметра:
• file — Указывает путь к файлу на сервере. Относительно текущей директории;
• virtual — Указывает виртуальный путь к документу на сервере.
Нас интересует параметр “virtual”, так как указывать полный путь до файла на сервере не всегда удобно, либо в случае распределенной архитектуры файла на сервере попросту нет. Пример директивы:
Для того, чтобы nginx начал обрабатывать ssi вставки, необходимо модифицировать location следующим образом:
Теперь все запросы, обрабатываемые location “/”, будут иметь возможность выполнять ssi вставки.
Как же во всей этой схеме будет проходить наш запрос?
Избавляемся от постоянных запросов к бэкенду через ssi
Для решения этой задачи нам поможет модуль nginx “ngx_http_memcached_module”. Модуль позволяет получать значения от сервера memcached. Записать через модуль не получится, об этом должен позаботиться сервер приложения. Рассмотрим небольшой пример настройки nginx в связке с модулем:
Если nginx удалось получить ответ от сервера кэша, то он отдает его клиенту. В случае когда данных в кэше нет, запрос будет передан на бэкенд через “@fallback”. Эта небольшая настройка memcached модуля под nginx поможет нам сократить количество проходящих запросов на бэкенд от ssi вставок.
Надеемся, эта статья была полезна и нам удалось показать один из способов оптимизации нагрузки на сервер, рассмотреть базовые принципы настройки nginx кэширования и закрыть возникающие проблемы при его использовании.