Главная / База знаний / Varnish Cache: ускоряем сайт кэшированием на уровне HTTP
инструкция · 2 октября 2026

Varnish Cache: ускоряем сайт кэшированием на уровне HTTP

Разбираем, как Varnish кэширует HTTP-ответы перед веб-сервером: структура VCL, пример конфигурации для анонимных посетителей, инвалидация кэша и сравнение с proxy-кэшем самого Nginx.

Что такое Varnish и где он находится в цепочке запроса

Varnish Cache — это специализированный HTTP-акселератор, задача которого — хранить в оперативной памяти уже полностью готовые HTTP-ответы и отдавать их повторным посетителям мгновенно, вообще не обращаясь к веб-серверу и приложению позади себя. В отличие от кэширования отдельных данных внутри приложения, Varnish кэширует финальный результат целиком — HTML-страницу вместе с заголовками ответа, готовую к немедленной отдаче клиенту.

В типичной схеме Varnish принимает весь входящий HTTP-трафик первым, ещё до веб-сервера, — то есть слушает 80 порт вместо Nginx или Apache, а сам веб-сервер (вместе с бэкендом приложения) переносится на другой порт, например 8080, и обращение к нему происходит только тогда, когда Varnish не может ответить из собственного кэша.

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

Основной принцип работы HTTP-акселераторов вроде Varnish

Эта статья разбирает базовую структуру конфигурации Varnish на языке VCL, пример настройки для типичного сайта с анонимными посетителями и авторизованной зоной, стратегии инвалидации кэша при обновлении контента, а также честное сравнение с встроенным кэшем самого Nginx и разбор того, когда полное кэширование страниц действительно ускоряет сайт, а когда создаёт больше проблем в виде устаревшего контента, чем пользы от скорости.

Архитектура: клиент — Varnish — бэкенд

Полная цепочка запроса при использовании Varnish выглядит так: клиент отправляет запрос на 80 (или 443, если TLS терминируется до Varnish) порт, где его принимает Varnish. Если подходящий ответ уже есть в кэше и не истёк его TTL, Varnish отдаёт его немедленно, не обращаясь дальше по цепочке вообще. Если ответа в кэше нет, истёк TTL, или запрос в принципе не подлежит кэшированию, Varnish обращается к бэкенду (веб-серверу на другом порту), получает от него ответ, при необходимости сохраняет его копию в собственном кэше и передаёт результат клиенту.

Определение бэкенда в конфигурации Varnish — веб-сервер на порту 8080
backend default {
    .host = "127.0.0.1";
    .port = "8080";
}

Поскольку сам Varnish в open-source версии не умеет самостоятельно терминировать TLS, для сайта на HTTPS типичная схема усложняется ещё одним слоем: TLS терминируется на Nginx, который затем проксирует уже расшифрованный трафик на Varnish, а Varnish, в свою очередь, обращается к другому Nginx (или тому же самому на другом порту) с самим приложением. Такая трёхзвенная схема выглядит сложнее одиночного Nginx, но каждое звено решает свою конкретную задачу, не дублируя функциональность соседних.

VCL: язык конфигурации Varnish

Vcl (Varnish Configuration Language) — специализированный язык, на котором описывается логика обработки запросов внутри Varnish. В отличие от декларативной конфигурации Nginx, VCL ближе к процедурному коду с явными условными конструкциями, что даёт заметно больше гибкости для нестандартной логики кэширования ценой более высокого порога входа в изучение.

Конфигурация VCL строится вокруг нескольких именованных подпрограмм (subroutines), каждая из которых вызывается на определённом этапе обработки запроса. vcl_recv выполняется сразу после получения запроса от клиента и решает, что с ним делать дальше — искать в кэше, передать напрямую на бэкенд без кэширования (pass) или обработать иначе. vcl_backend_response выполняется после получения ответа от бэкенда и решает, стоит ли сохранять этот ответ в кэш и на какой срок.

Минимальный скелет файла default.vcl с двумя основными подпрограммами
vcl 4.1;

backend default {
    .host = "127.0.0.1";
    .port = "8080";
}

sub vcl_recv {
    # Логика на этапе получения запроса от клиента
}

sub vcl_backend_response {
    # Логика на этапе получения ответа от бэкенда
}

Важная особенность VCL — встроенная логика по умолчанию не отключается полностью, а дополняется: если в написанном администратором коде подпрограммы явно не указано действие (return), Varnish продолжает выполнение встроенной логикой по умолчанию, которая уже содержит разумные базовые правила — например, не кэшировать запросы с cookie или с методом, отличным от GET и HEAD.

Практический пример: кэшируем анонимных посетителей, пропускаем авторизованных

Типичная и самая частая задача — кэшировать страницы для анонимных посетителей (тех, у кого нет cookie авторизации или корзины), пропуская мимо кэша всё, что относится к персонализированному контенту конкретного пользователя.

Пропуск авторизованных запросов и служебных разделов мимо кэша в vcl_recv
sub vcl_recv {
    if (req.http.Cookie ~ "(session_id|logged_in|cart)") {
        return (pass);
    }

    if (req.url ~ "^/(cart|checkout|account|wp-admin)") {
        return (pass);
    }

    unset req.http.Cookie;
}

Первое условие проверяет наличие в заголовке Cookie значений, характерных для авторизованной сессии, корзины или залогиненного пользователя, — если такие cookie присутствуют, запрос направляется командой return (pass) напрямую на бэкенд, минуя кэш полностью. Второе условие дополнительно исключает из кэширования по URL целые разделы сайта, которые в принципе не должны кэшироваться независимо от наличия cookie — админку, страницу корзины, оформление заказа.

Директива unset req.http.Cookie для оставшихся (анонимных) запросов удаляет заголовок Cookie перед поиском в кэше и обращением к бэкенду — по умолчанию Varnish не кэширует запросы с любым заголовком Cookie вообще, считая их потенциально персонализированными, и явное удаление cookie для действительно анонимных посетителей (без сессии, корзины и авторизации) позволяет таким запросам всё же попадать в кэш.

Установка TTL для закэшированного ответа и защита от кэширования ответов с новыми cookie
sub vcl_backend_response {
    if (beresp.http.Set-Cookie) {
        return (deliver);
    }
    set beresp.ttl = 5m;
    set beresp.grace = 1h;
}

Проверка beresp.http.Set-Cookie в vcl_backend_response — дополнительная защита в обратную сторону: если сам бэкенд в ответе устанавливает новый cookie (например, начинает новую сессию для этого конкретного посетителя), такой ответ не должен кэшироваться и раздаваться следующим посетителям с чужим персональным cookie внутри. Параметр beresp.grace задаёт время, в течение которого Varnish может отдать уже устаревший (просроченный) кэш, если бэкенд в этот момент недоступен, — полезная защита от полного падения сайта при кратковременной проблеме на стороне веб-сервера или приложения.

TTL и заголовки Cache-Control от бэкенда

Время жизни закэшированного ответа (TTL) Varnish определяет по нескольким источникам в порядке приоритета: явное значение, заданное в VCL через beresp.ttl, переопределяет автоматическое поведение; при отсутствии явного значения Varnish ориентируется на заголовки Cache-Control и Expires, полученные от самого бэкенда в ответе.

Такое поведение позволяет распределить ответственность между конфигурацией Varnish и логикой самого приложения: приложение может явно указывать через заголовок Cache-Control: max-age=600, что конкретная страница актуальна в течение 10 минут, а Varnish будет ориентироваться именно на это значение для конкретного ответа, вместо единого глобального TTL для всех страниц сайта без разбора их реального характера обновления.

Выбор TTL — всегда компромисс между актуальностью данных и эффективностью кэша, аналогично выбору TTL для любого другого слоя кэширования: слишком короткий TTL означает частые обращения к бэкенду и малую практическую пользу от кэша, слишком длинный — риск показать посетителям устаревшую информацию дольше, чем это приемлемо для конкретного типа контента на сайте.

Инвалидация кэша: PURGE, BAN и классическая проблема

Простое истечение TTL по времени решает задачу свежести данных с некоторой задержкой, но для многих сценариев такая задержка неприемлема — например, когда редактор сайта только что опубликовал исправление в статье и ожидает увидеть изменения немедленно, а не через оставшиеся минуты TTL. Для этого в Varnish есть механизмы явной принудительной инвалидации.

Обработка HTTP-метода PURGE для явного сброса конкретного URL из кэша
sub vcl_recv {
    if (req.method == "PURGE") {
        return (purge);
    }
}

Метод PURGE полностью удаляет из кэша конкретный объект по точному URL — CMS или система публикации контента может автоматически отправлять такой запрос сразу после сохранения изменений на конкретной странице, обеспечивая мгновенное обновление кэша именно для изменившегося URL без ожидания истечения TTL. Более гибкий, но и более тяжёлый по нагрузке механизм — BAN, который помечает недействительными сразу множество объектов кэша по шаблону (например, все URL, начинающиеся с определённого префикса), а не по точному совпадению одного адреса.

Есть только две по-настоящему сложные вещи в компьютерных науках: инвалидация кэша и придумывание имён.

Известная шутка из мира разработки программного обеспечения

Практическая сложность инвалидации в том, что она требует интеграции между CMS или приложением и самим Varnish — недостаточно просто настроить Varnish отдельно от остальной инфраструктуры, нужно, чтобы приложение при каждом изменении контента явно уведомляло Varnish о необходимости сбросить кэш конкретных затронутых URL, что требует дополнительного кода или готового плагина интеграции для конкретной CMS.

Varnish против встроенного кэша Nginx

Nginx умеет кэшировать полные HTTP-ответы самостоятельно, без Varnish, через директивы proxy_cache (для проксируемых бэкендов) или fastcgi_cache (для PHP-FPM) — функционально это решает похожую задачу: сохранить готовый ответ и отдавать его повторным запросам без обращения к бэкенду.

Пример настройки proxy_cache в Nginx как альтернативы Varnish
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g;

location / {
    proxy_cache my_cache;
    proxy_cache_valid 200 10m;
    proxy_cache_bypass $cookie_session;
    proxy_pass http://127.0.0.1:8080;
}

Ключевое практическое различие — не в самой возможности кэширования (оба инструмента с этим справляются), а в гибкости логики и удобстве работы со сложными сценариями. VCL Varnish, будучи полноценным процедурным языком, заметно удобнее для нетривиальной логики: множественных условий, разной обработки в зависимости от заголовков, кастомной логики инвалидации через PURGE и BAN. Конфигурация proxy_cache в Nginx декларативна и прекрасно справляется с типичными сценариями, но сложную специфичную логику в неё встраивать заметно менее удобно.

Практический выбор чаще определяется не абстрактным превосходством одного инструмента над другим, а конкретной ситуацией: если сайт уже работает на Nginx и нужно простое кэширование типичных страниц без сложной логики — proxy_cache или fastcgi_cache Nginx решает задачу без добавления ещё одного компонента инфраструктуры. Если нужна тонкая, нестандартная логика кэширования, интеграция с системой инвалидации через PURGE, или сайт уже спроектирован вокруг Varnish исторически — отдельный Varnish перед веб-сервером оправдан. Общее сравнение подходов и философии Nginx как веб-сервера разобрано в отдельной статье базы знаний.

Когда полное кэширование страниц помогает, а когда создаёт баги

Полное кэширование HTTP-ответов даёт наибольший эффект там, где значительная часть трафика приходится на анонимных посетителей, видящих одинаковый контент, — новостные сайты, блоги, каталоги товаров без персонализации цен, лендинги. Для такого профиля трафика Varnish способен принять на себя подавляющее большинство запросов, вообще не нагружая веб-сервер и базу данных позади себя, что напрямую влияет на метрики скорости загрузки и, соответственно, на Core Web Vitals сайта.

Обратная сторона медали проявляется на сайтах с высокой долей персонализированного или часто меняющегося контента: интернет-магазины с индивидуальными скидками или динамическими остатками на складе, личные кабинеты, сайты с активной авторизацией пользователей. Здесь риск показать одному посетителю закэшированную страницу, предназначенную для другого (с чужой корзиной, чужими персональными данными или устаревшей ценой), реален при недостаточно аккуратной настройке VCL, и последствия такой ошибки — не просто неудобство, а потенциальная утечка чужих данных.

Практическое правило: чем более статичен и одинаков контент страницы для разных посетителей, тем больше пользы от полного кэширования на уровне Varnish; чем сильнее содержимое зависит от конкретного пользователя, тем более узкой и тщательно проверенной должна быть зона того, что вообще попадает в кэш, вплоть до полного исключения из кэширования отдельных разделов сайта, где риск показать чужие данные перевешивает выигрыш в скорости.

Мониторинг: varnishstat и varnishlog

Varnish поставляется с собственными инструментами мониторинга без необходимости внешних систем для базовой диагностики. Команда varnishstat выводит статистику в реальном времени — число попаданий и промахов кэша, объём использованной памяти, количество обработанных запросов в секунду.

Проверка hit rate кэша и просмотр детального лога обработки запросов
varnishstat -1 | grep -E 'cache_hit|cache_miss'
varnishlog -g request

Низкое отношение cache_hit к cache_miss обычно означает одну из нескольких типичных причин: слишком короткий TTL для реального профиля обновления контента, слишком широкие условия пропуска мимо кэша (например, случайно попавший под условие pass раздел, который на самом деле мог бы кэшироваться), или структурно высокая доля запросов, которые в принципе не подлежат кэшированию по своей природе — динамических API-запросов, персонализированного контента.

varnishlog даёт детальную трассировку обработки конкретных запросов — какая подпрограмма VCL была выполнена, было ли решение return (pass) или return (hash) для поиска в кэше, какой конечный статус получил ответ. Это незаменимый инструмент при отладке ситуации, когда конкретная страница ведёт себя не так, как ожидалось согласно написанной логике VCL.

Чек-лист внедрения Varnish

Шаг 1. Определите профиль трафика сайта: высокая доля анонимных посетителей с одинаковым контентом — хороший кандидат на полное кэширование; много персонализированного контента — начните с малого, кэшируя только заведомо безопасные разделы.

Шаг 2. Настройте базовый VCL с явным исключением авторизованных запросов, корзины и служебных разделов из кэша через анализ cookie и URL.

Шаг 3. Настройте адекватный TTL под реальную частоту обновления контента — ориентируясь либо на заголовки Cache-Control от приложения, либо на явные значения в VCL.

Шаг 4. Реализуйте механизм принудительной инвалидации (PURGE или BAN) и интегрируйте его с публикацией контента в CMS, чтобы изменения появлялись сразу, а не только после истечения TTL.

Шаг 5. Настройте мониторинг hit rate через varnishstat на постоянной основе, чтобы видеть реальную эффективность кэша, а не полагаться на предположения о его работе.

Шаг 6. Протестируйте сценарии с авторизацией и персонализированным контентом отдельно, убедившись, что ни один посетитель не может увидеть закэшированную страницу, предназначенную для другого пользователя.

Итог: мощный инструмент, требующий аккуратной настройки

Varnish способен радикально ускорить сайт с подходящим профилем трафика, сняв с веб-сервера и базы данных большую часть нагрузки от повторяющихся запросов к одинаковому контенту. Гибкость VCL делает его удобным инструментом для нестандартной логики кэширования, недоступной или неудобной в декларативной конфигурации proxy_cache стандартного Nginx.

Эта мощь одновременно требует ответственности: неаккуратно настроенное кэширование персонализированного контента способно не просто испортить пользовательский опыт устаревшими данными, а привести к показу чужих личных данных другому посетителю. Если сомневаетесь, подойдёт ли Varnish конкретному профилю вашего сайта, или нужна помощь с настройкой VCL под конкретную логику кэширования — опишите задачу в заявке внизу страницы.

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

почему мы

Почему стоит выбрать нас

Быстрый запуск

Подберём конфигурацию и развернём проект в день обращения.

Надёжность

NVMe-диски, защита от DDoS и резервные копии по расписанию.

Поддержка 24/7

Дежурные инженеры на связи в любое время суток.

Настройка под ключ

Установим CMS, настроим веб-сервер, SSL и почту за вас.

Перенос без простоя

Аккуратно перенесём сайт и базу данных на новый сервер.

Прозрачные цены

Актуальные тарифы и честный подбор без навязывания.

частые вопросы

Вопросы и ответы

Чем Varnish отличается от обычного кэширования на уровне приложения?

Varnish кэширует полностью готовый HTTP-ответ (HTML-страницу целиком, вместе с заголовками) ещё до того, как запрос доходит до веб-сервера и приложения, тогда как кэширование на уровне приложения (например, через Redis) обычно кэширует отдельные данные или фрагменты, которые всё равно собираются в полную страницу кодом приложения при каждом запросе.

Можно ли использовать Varnish с сайтом на HTTPS?

Сам Varnish исторически не умеет терминировать TLS самостоятельно, поэтому типичная схема — TLS терминируется на Nginx или отдельном балансировщике перед Varnish, который дальше работает с расшифрованным HTTP-трафиком; современные версии Varnish Enterprise добавили встроенную поддержку TLS, но в open-source версии этот компонент по-прежнему выносится вовне.

Что произойдёт, если Varnish закэширует страницу с чужими персональными данными?

Это одна из самых опасных ошибок конфигурации VCL — если страница с данными конкретного пользователя (например, личный кабинет) закэширована без учёта cookie сессии, следующий посетитель, попавший на тот же URL, получит закэшированную версию с чужими персональными данными; именно поэтому исключение авторизованных запросов из кэша — обязательная, а не опциональная часть настройки.

Как долго Varnish хранит закэшированный ответ?

Ровно столько, сколько указано в TTL (time to live), который определяется либо явно в VCL, либо на основе заголовков Cache-Control и Expires, полученных от бэкенда, — по истечении этого времени Varnish обратится к бэкенду заново при следующем запросе и обновит закэшированную копию.

В чём разница между Varnish и FastCGI-кэшем Nginx?

Функционально оба решают похожую задачу — кэширование полных HTTP-ответов, но Varnish изначально спроектирован именно как специализированный HTTP-акселератор с собственным гибким языком конфигурации VCL для сложной логики кэширования, тогда как кэш Nginx (fastcgi_cache или proxy_cache) — это дополнительная возможность универсального веб-сервера, более простая в настройке для типичных сценариев, но менее гибкая для нестандартной логики.

Нужно ли устанавливать Varnish отдельно от Nginx или Apache?

Да, Varnish — отдельный процесс, который обычно принимает трафик первым (на 80 порту) и проксирует незакэшированные или непригодные для кэширования запросы на веб-сервер, слушающий уже другой порт (например, 8080) — Varnish и Nginx работают в связке, а не заменяют друг друга.

Что делать, если после изменения контента сайт продолжает показывать старую версию страницы?

Это классическая проблема инвалидации кэша — нужно либо дождаться истечения TTL закэшированной страницы, либо явно сбросить кэш конкретного URL через команду PURGE или BAN, настроенную в VCL, что обычно автоматизируют хуком в CMS при публикации нового контента.

Подходит ли Varnish для интернет-магазина с персонализированными ценами и корзиной?

С осторожностью — страницы каталога и карточки товаров с одинаковым содержимым для всех посетителей кэшируются прекрасно, но страницы с корзиной, персональными скидками или содержимым, зависящим от сессии конкретного пользователя, нужно явно и корректно исключать из кэша в VCL, иначе один посетитель рискует увидеть содержимое корзины другого.

Как оплачивать услуги?

Оплата помесячная, для облачных серверов доступна почасовая тарификация. Принимаются карты, банковские переводы и электронные кошельки.

Есть ли круглосуточная поддержка?

Да, дежурные инженеры на связи 24/7.

Выдаёте ли закрывающие документы?

Да, предоставим необходимые документы для оплаты.

Как оставить заявку?

Заполните форму на странице или нажмите «Заказать» — мы свяжемся и поможем с подбором.

заявка

Оставьте заявку

Ответим и поможем с подбором и настройкой.