Динамические сайты со скоростью статических: искусство кэширования сайта

Уже немало было сказано о достоинствах статических сайтов. Но в большинстве случаев необходим динамический подход. Будь то система контент-менеджмента, инструмент для работы с клиентами или онлайн-магазин, все они позволяют конечному пользователю быстро и равномерно сохранять сложные сайты. А если правильно их сочетать, они могут обогнать по скорости статичные сайты.
Вне зависимости от того, какую систему вы используете, динамические сайты, как правило, состоят из одинаковых элементов. Среди этих элементов форма веб-сервера, backend и приложение, написанное на одном или нескольких языках программирования. Такое сочетание компонентов дает неплохую гибкость, но каждый элемент привносит свои собственные издержки и увеличивает время загрузки, чего все современные сайты стараются избегать. Особенно это касается доступа к базе данных; любое приложение, которому нужно постоянно считывать и записывать данные, может привести к ощутимой задержке.
В таком случае вам поможет кэширование и правильно подобранная для вашего конкретного случая стратегия кэширования. Основная цель кэширования предотвратить ненужные частые вызовы между слоями базы данных приложения, и вместо этого использовать предварительно сгенерированные статичные HTML-страницы, которые намного быстрее отрисовываются в браузере.
Кэширование браузера
Первый кэш, работу которого замечает каждый пользователь сети это кэш браузера. Сколько раз разработчики просили вас обновить страницу, чтобы увидеть изменения? Кэш браузера довольно прост, но это хорошее начало для объяснения концепции кэширования. Браузер сохраняет описания страниц, которые пользователь посещал со своего компьютера, как правило, обновляя их один раз за сессию, если на сайте были замечены обновления.
Прокси-кэширование
Основной инструмент, используемый владельцами и администраторами сайтов, это кэширование обратного прокси-сервера, который стоит между запросами страницы, создаваемыми браузером, и веб-приложением. Оно перехватывает запросы и отрисовывает копии страниц непосредственно из кэша, тем самым обеспечивая существенное повышение скорости.
Существует несколько основных вариантов прокси-кэша, которые можно самостоятельно установить, или которые подставляют собой \"программное обеспечение как услугу\". (Мы опускаем провайдеров облачных хостингов, которые, как правило, собирают все, что вам нужно, в один самостоятельный веб-стек).
Популярные варианты прокси-кэша включают:
- Varnish (см. ниже);
- Squid;
- Nginx (сочетание веб-сервера и прокси-кэша).
- Squid;
Варианты SaaS для кэширования в основном заключаются в сетях доставки контента (CDN), которые, вместо того, чтобы размещать кэш между пользователем и веб-стеком, представляют пользователям наборы кэшированного контента ссерверов, которые географически расположены наиболее близко к ним. Разница незначительна, но для больших сайтов с глобальной аудиторией эта разница может оказаться существенной.
Использование Varnish
Varnish доступен во всех менеджерах пакетов для Linux, в качестве изображений Docker и других вариантов. Подробнее об этом проекте вы можете прочитать на его установочной странице.
Базовые конфигурации Varnish
Varnish сохраняет файл конфигураций по умолчанию либо в at/usr/local/etc/varnish/default.vcl либо в /etc/varnish/default.vcl, записанный на VCL (язык конфигурации Varnish). Этот файл конфигураций компилируется в небольшую программу через интерпретатор С, еще больше увеличивая скорость. В зависимости от того, как вы установили Varnish, файл конфигураций может выглядеть следующим образом:
backend default { .host = \"127.0.0.1\"; .port = \"8000\"; }
Простыми словами, это определяет стандартный backend, используемый Varnish, определяя хост и порт, который он должен отслеживать и на котором он должен перехватывать контент.
Backend-опрос
Одна из наиболее полезных функций Varnish проверка с заданными интервалами, работает ли backend. Это называется backend-опрос , и настраивается он путем добавления секции сбора информации в декларацию backend:
.probe = { .url = '/'; .timeout = 34ms; .interval = 1s; .window = 10; .threshold = 8; }
Выше приведены настройки по умолчанию, предоставленные Varnish, которые говорят ему, что он должен заходить на определенный .url каждый .interval, и если как минимум в .threshold случаях из количества опросов .window url отвечает в течение .timeout миллисекунд, тогда backend считается исправным. Как только backend будет определен как неисправный , контент будет подаваться из кэша на протяжении предварительно заданного промежутка времени.
Запуск Varnish
Мы рассмотрим особые изменения, которые нужно внести в конфигурации Varnish для каждой платформы, но сейчас давайте рассмотрим общие опции.
Порты
Изначальное значение по умолчанию порта вашего веб-сервера нужно изменить. Например, в конфигурациях Apache Vhost порт нужно изменить на 81 или 8080.
Запустите Varnish Daemon с помощью команды varnish или используя надстройку сервиса. В Daemon есть опции флага, среди которых наиболее полезными являются:
- -f: Задает путь к файлу конфигураций.
- -s: Опции хранения кэша. Если задать RAM, то это обеспечит еще большую скорость.
Проверяем, все ли работает
Запустите команду varnishstat или зайдите на сайт isvarnishworking.com, чтобы проверить, что ваш сервер Varnish готов и принимает запросы.
Что не стоит кэшировать
Существуют некоторые части сайта, которые нам не следует кэшировать, например, админка. Мы можем исключить их, создав подпрограмму vcl_recv в файле default.vcl, который содержит оператор if, определяющий, что не нужно кэшировать:
sub vcl_recv { # URI of admin folder if (req.url ~ \"^/url/\") { return (pass); } return(lookup); }
Если вы используете Varnish 4, все будет выглядеть немного иначе, включая возвращаемые значения. Функция vcl_recv теперь возвращает значение ahash вместо поиска.
sub vcl_recv { ... return(hash); }
Тут же мы задаем сайты и поддомены, которые Varnish должен игнорировать, добавляя req.http.host ~ example.com в оператор if.
Куки
По умолчанию Varnish не будет кэшировать контент с backend, который задает куки. Таким же образом, если клиент отправляет куки, он будет обходить Varnish и отправлять их прямо на сервер.
Куки часто используются сайтами для отслеживания пользовательской активности и сохранения значений пользователей. В основном такие куки интересны только для клиентского кода и не интересны для backend или Varnish. Мы можем указать Varnish игнорировать куки, за исключением определенных зон сайта:
if ( !( req.url ~ ^/admin/) ) { unset req.http.Cookie; }
Этот оператор if игнорирует куки, если только они не в админке сайта, где сбор куки может принести больше пользы (если только вы не хотите вывести из себя администраторов сайта).
Прочие исключения
При установке по умолчанию Varnish также не кэширует страницы, защищенные паролем, запросы GET и HEAD.
Пускаем Varnish в работу
Теперь давайте рассмотрим два идеальных случая использования Varnish: Drupal и Magento. Обе эти системы являются высокодинамичными и позволяют пользователям без технического образования довольно легко выполнять огромное количество разнообразных сложных задач. Это может привести к нагрузке страницы базой данных с тяжелыми запросами, и активные сайты могут стать значительно медленнее. Стандартные страницы, построенные с помощью данных систем, будут сочетать в себе часто и нечасто обновляемый контент.
Drupal
В Drupal есть опции кэширования по умолчанию, которые выполняют функции, подобные Varnish, но не обеспечивают гибкости или повышения скорости, необходимых для крупных и более сложных сайтов.
В Drupal есть модуль для интегрирования Varnish, позволяющий сохранять некоторые ручные конфигурации, описанные выше.
Установите этот модуль и соблюдайте инструкции по установке, приведенные в файле Read Me модуля.Убедитесь, что для файла /etc/default/varnish настроены следующие опции демона (структура текста важна):
DAEMON_OPTS=\"-a :80 \ -T localhost:6082 \ -f /etc/varnish/default.vcl \ -S /etc/varnish/secret \ -s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,128M\"
Убедитесь, что Apache и любые другие связанные с ним виртуальные хосты отслеживают порт 8080, а не 80. Перезагрузите оба сервиса, после того, как внесете эти изменения.
Возможно, вам потребуется настроить Varnish Control Key (ключ управления Varnish) на странице конфигураций модуля. Найдите, какой это ключ, выполнив команду cat /etc/varnish/secret, и вставьте его на странице настроек. Выберите правильную версию Varnish, сохраните настойки, и вы увидите набор зеленых отметок внизу страницы.
Модуль Varnish взаимодействует со стандартными настройками кэша Drupal, поэтому убедитесь, что вы его включили и настроили в соответствии со своим случаем.
Выполните команду varnishstat в командной строке, начните перемещаться по сайту анонимно, и вы увидите, как будут изменяться статистические данные в командном выводе.
Одна из частей сайта, которую мы не хотим кэшировать в Drupal это страницы админки. Сделать это можно через подпрограмму vcl_recv:
sub vcl_recv { # URI of admin folder if (req.url ~ \"^/admin/\") { return (pass); } unset req.http.Cookie; return(lookup); }
Возможно, вы хотите отключить кэширование пользовательских страниц (залогиненных), страниц системных обновлений и прочих страниц, сгенерированных высокодинамичными модулями, такими как флаг, которые активно используют ajax. Сделать это можно путем добавления параметров req.url в оператор if.
Magento
Стандартная установка Magento предоставляет вам систему внутреннего кэширования, которая сохраняет статичные версии элементов сайта в указанной папке. Страница System -> Cache Management предоставляет обзор текущего состояния кэша, а также позволяет вам очистить все или отдельные компоненты кэша. Вы можете очистить накопленные файлы CSS и JS и автоматически сгенерированные файлы изображений, полученные с этой страницы.
Предстоящая версия 2 Magento будет поддерживать кэширование Varnish по умолчанию, но на данный момент нам нужно использовать сторонние плагины. Я рекомендую модуль Turpentine. Обязательно ознакомьтесь с файлом readme этого проекта, так как в нем указаны некоторые дополнительные этапы настройки, игнорирование которых может обрушить ваш сайт.
Модуль Turpentine легко предоставляет обширные возможности настройки и вносит необходимые изменения в файлы vcl и конфигурации Varnish. Среди ключевых опций, которые нужно настроить:
- Backend Host: Хост Varnish, по умолчанию - 127.0.0.1
- Backend Port: Порт, на котором запущен Varnish, по умолчанию - 80
- URL Blacklist: Список URL, которые никогда не кэшируются по отношению к корневому каталогу Magento. URL админки и API включены автоматически.
- Backend Port: Порт, на котором запущен Varnish, по умолчанию - 80
Модуль Turpentine связан со стандартным кэшем Magento, поэтому при очистке страницы кэша Varnish, очистится и соответствующий кэш в Magento?
Основные советы
Кроме использования Varnish с различными динамическими системами, представленными выше, вот вам несколько советов, которые помогут улучшить способность кэширования любого сайта.
Последовательные URL
Если вы представляете один и тот же контент в различных контекстах, он должен использовать один и тот же URL. Например, не стоит одновременно использовать article.html, article.htm и article, однако ваш CMS может это позволять. Это приведет к трем различным кэшированным версиям одного и того же контента.
Используйте куки рационально
Как мы видели выше, куки сложно кэшировать, и они редко столь необходимы, как нам кажется. Постарайтесь ограничить их использование и сократить количество динамических страниц.м
Управление файлами
Использование спрайтов CSS Image для иконографии нескольких небольших файлов приведет к снижению потребления сетевого трафика Локальный хостинг библиотек CSS и JavaScript приводит к меньшему потреблению сетевого трафика и большему контролю над стратегиями кэширования. Это может означать увеличение затрат на техническое обслуживание для поддержания актуальности этих ресурсов. Сохраняйте эти ресурсы в последовательно поименованных папках, чтобы ссылки на них также были последовательными.