В одной из предыдущих статей мы рассмотрели, каким образом можно реализовать кеширование страниц с помощью Varnish и ESI. В этой статье рассмотрим альтернативное решение — на основе двух суперзнаменитых продуктов — nginx и memcached.
Оба не нуждаются в представлении, а о том, как на основе их можно значительно увеличить эффективность работы Вашего сайта, поговорим ниже.
В качестве краткого повторения, несколько основных идей и преимуществ кеширования на уровне странц:
Кешируя страницы на отдающем сервере, Вы освобождаете ощутимое количество ресурсов на бекендах
В случае медленных страниц, значительно уменьшается время ожидания страниц Вашего сайта (ускоряется его работа)
Как показывает практика, во многих случаях внедрять систему кеширования странц в готовый проект легче, чем систему кеширования запросов
Nginx и memcached
Nginx позволяет читать данные из Мemcached — для этого Вам необходим модуль HttpMemcachedModule.
Самый простой пример — проверяем есть ли страница в кеше и, если есть, достаем из кеша, иначе — делаем запрос к бекенду.
server { location / { set $memcached_key $uri; # Ключ для проверки в memcached memcached_pass 127.0.0.1:11211; # Параметры подключения default_type text/html; # Заголовок по умолчанию error_page 404 @fallback; # 404 — данные в кеше не найдены }
В данный момент Nginx не умеет сохранять значения в memcached — только читать данные. Значит задача по сохранению страниц в кеш ложится на бекенд. Выглядит это приблизительно так (PHP):
<? $memcache = new Memcache(); # какой-то код
ob_start(); # визуализация страницы — html $html = ob_get_clean();
Если у Вас не самый примитивный сайт (а он у Вас не такой), логика кеширования страниц будет несколько усложнена различными динамическими элементами страницы (блок авторизации, динамическое меню и т.п.). Подобные задачи решаются c помощью SSI — server side includes. Кроме всего прочего использование SSI экономит память, т.к. для каждой страницы Вы не будете хранить ее исходник целиком, а только внутреннюю (изменяемую) часть.
Синтаксис SSI очень простой и выглядит так:
<!--# include virtual="/authentication.php" -->
Следует отметить, что SSI — это уровень Web сервера. Для прилжения этот механизм полностью прозрачен. В приведенном примере, на месте вызова SSI, Web сервер (nginx) просто сделает еще один запрос к бекенду. Например, если у Вас два SSI вызова на страницу, то клиентский запрос к каждой странице будет генерировать три запроса к бекенду. Конечно, само по себе это бессмысленно, но в связке с кешированием представляет из себя мощный инструмент оптимизации систем.
Практический пример
Теперь соберем все выше изложенное в последовательный рецепт решения рассматриваемой задачи.
Для начала Вам необходимо выделить блоки в Вашем базовом (глобальном) шаблоне и заменить их вызовами SSI. Пример на PHP:
<html> <body>
<h1>Тестируем nginx + memcached + ssi</h1>
<div class="auth">
<!--# include virtual="/authentication.php" --> </div>
<!--# include virtual="/somepage.php" -->
</body> </html>
Как видно, на странице есть два блока — блок авторизации и контентный блок (содержимое странички). В нашем примере блок авторизации будет персональным (допустим, после входа, там будет имя пользователя). Блок содержимого не будет персональным (т.е. он будет общим для всех пользователей).
Теперь необходимо настроить nginx для обработки SSI вызовов и использованию memcached:
# Upstream бекенда upstream backend { server 127.0.0.1:8081; }
server { listen 80; server_name test.com;
root /var/www/test; index index.php;
location / { # Все POST запросы отправляем на бекенд (не кешируя) if ($request_method = POST) { proxy_pass http://backend; break; }
Следующим шагом в приложении необходимо будет реализовать сохранение исходников страниц в memcached.
Кеширование персонализированных блоков
Ясно, что для кеширования персонализированных блоков необходимо добавить идентификатор пользователя (не вздумайте использовать внутренний ID пользователя) в ключ memcached. SSI вызов необходимо пометить, чтобы отличать персональные блоки от общих. Т.е. персональный вызов SSI будет иметь такой вид:
<!--# include virtual="/uid/authentication.php" --> </div>
Для генерации memcached ключей с идентификатором пользователя можно использовать куки (устанавливать его будет приложение при авторизации пользователя):
set $memcached_key "$uri:$cookie_uid";
Соответственно, необходимо в nginx добавить обработчик для “/uid” запросов:
Недавно появился продукт, который должен стать типичным решением при кешировании страниц — Twicecache. Пока он на очень ранней стадии и доступны только его исходники. Будем внимательно следить.
Комментариев нет:
Отправить комментарий