|
||
Ответить |
|
#1
|
|
Вес репутации:
0
Регистрация: 27.02.2009
Адрес: Москва
Сообщений: 7,302
Сказал(а) спасибо: 578
Спасибок 2,627
в 1,832 сообщениях |
Кеширование блоков с помощью nginx -
07.06.2010, 18:50
Многим разработчикам знакома ситуация когда кешировать страницы сайта, скажем, на 5-10 минут нельзя всего из-за одного небольшого блочка, актуальность которого нужно поддерживать если не в реальном времени, то с временем «старения» не больше 5-10 секунд. При этом посещаемость сайта продолжает расти, растет время генерации страниц и c этим надо что-то делать…
Как это должно работать Cайт всегда можно разбить на некоторое число независимых блоков, генерацией которых может заниматься (при необходимости) разные сервера. При этом сборкой блоков в единое целое занимается некий «сборщик» и если любой из блоков по какой-то причине не создан за отведенное ему время, то это еще не повод выдавать клиенту «Gateway timeout» или «Internal Server Error». Можно собрать успешно созданные блоки, а на месте «сбойных» показывать устаревший контент из кеша. Для реализации такой модели нам понадобиться технология-ветеран Web-разработки: ssi. В качестве «сборщика», как ясно из названия статьи, выступает nginx. «Чудеса» станут возможны благодаря модулю fastcgi_cache. Итак, поехали: Исключаем лишнее звено Нам не пригодиться apache, наличие которого, как правило объясняется использованием RewriteRules. В nginx есть аналог mod_rewrite или комбинация location/alias с регулярными выражениями, возможности которых позволяют написать аналог любому RewriteRule от apache. Кроме того в современных фреймворках разбором входного URL может заниматься сам движек (например Zend_Controller_Router_Rewrite в Zend Framework) В качестве fastcgi-бекенда может использоваться любая платформа. Примеры будут на php, но это не означает что нельзя написать аналогичный код на python-е или perl-е. Запускаем php в режиме fastcgi: # /bin/su -m www_user -c "PHP_FCGI_CHILDREN=8 /usr/bin/php-cgi -q -b 127.0.0.1:7777 &" Делаем: # killall php-cgi Более продвинутый вариант запуска fastcgi — установка php-fpm. Устанавливаем nginx Можно ставить стандартный из репозитория/портов… Но если хотите чтоб работала возможность «почистить» любой файл в кеше, придется компилировать. Нам понадобиться модуль: ngx_cache_purge Я подробно опишу, как это можно сделать для redhat-подобной системы, а вы уж по аналогии компилируйте под вашу систему. # cd ~/rpmbuild/SRPMS # yumdownloader --source nginx # rpm -ivh nginx-0.7.65-1.fc12.src.rpm теперь распаковываем содержимое http://labs.frickle.com/files/ngx_ca...rge-1.0.tar.gz в папку /root/rpmbuild/BUILD/ngx_cache_purge-1.0. Все можно компилировать: # cd ~/rpmbuild/SRPMS # rpmbuild -ba nginx.spec Устанавливаем пересобранный nginx на наш сервер: # rpm -ivh nginx-0.7.65-1.fc12.x86_64.rpm В файл /etc/hosts (добавляем): PHP код:
PHP код:
В папке /etc/nginx/conf.d/ создаем конфиги для виртуальных хостов Пример кофига (/etc/nginx/conf.d/myproject.conf): PHP код:
Запускаем nginx. Для RedHat-подобных систем это выглядит приблизительно так: # service nginx start Учим backend управлять временем кеширования Дело в том, что в nginx время кеширования указывается в параметре fastcgi_cache_valid 200 0m; и распространяется на все страницы, в которых заголовком оно не переопределено. В конфиге «по умолчанию» время кеширования я указал равным 0, т.е. кеширование отключено. Но если бекенд сгенерирует заголовок приблизительно такого вида: Cache-Control: public, max-age=20 либоExpires: Thu, 18 Mar 2010 2007 GMT То страница nginx-ом будет закеширована на 20 секунд. В php заголовок можно поменять с помощью функции header() (Со слов автора nginx самым приоритетным является «X-Accel-Cache-Control», потом «Cache-Control», потом «Expires»). Напишем небольшую функцию. котрая будет управлять временем кеширования: PHP код:
Блоком будем называть любую логически выделенную часть html-кода без стандартных заголовков html-старницы, например: PHP код:
PHP код:
Удаляем страницы из кеша К сожалению у nginx-а пока что нету родного (штатного) способа удаления страничек из кеша. Иногда это может создавать неудобства. Если вы добавили при компиляции модуль ngx_cache_purge, то в конфиг (/etc/nginx/conf.d/myproject.conf) добавим приблизительно такую секцию, перед секцией «location / {...» : PHP код:
В php это можно сделать командой file_get_contents(«http://myproject/purge/mypage.php?lang=ru»); С помощью директив allow и deny можно ограничить круг хостов с которых можно «чистить» кеш. Тестируем Напоминаю, ссылка для тестов Пример кеширования блоков с помощью nginx. Обратите внимание, «каркас» страницы обновляется раз в 10 секунд, остальные блоки обновляются согласно примечаниям под временем создания блока. Самый большой интерес, на мой взгляд, представляет «Збойный блок». Если вы введете его в режим имитации сбоя, вы все равно будете видеть «несбойную» версию этого блока пока не очистите кеш. Кроме того, помните, что вы не одни сейчас проводите эксперименты с этой страничкой, если хотите поэкспериментировать — самостоятельно настройте локальную копию примера. Делаем выводы Даже если такой подход покажется Вам примитивным, и функциональность его сильно ограниченной, обратите внимание на то, что это работает не просто быстро, а очень быстро! Узким местом может быть только дисковая система, если кеш «распухнет» до больших размеров и не будет помещаться в дисковый кеш. Источник <!-- Вопросы задаем на форуме, не в ЛС --> |
Ответить |
Опции темы | |
Опции просмотра | |
|
|