Настройка Varnish Cache для HTTP-акселерации
Отметим: когда backend выдает ответ за 300-500 мс, а пользователь ожидает страницу за 50 мс, обычный nginx-кэш не дает нужного ускорения. Varnish Cache решает эту задачу на уровне ядра: он хранит ответы в оперативной памяти и обрабатывает десятки тысяч запросов в секунду на стандартном оборудовании. Например, при нагрузке 10 000 RPS Varnish способен отдавать кэшированные ответы за 1-2 мс, в то время как nginx с кэшем — за 5-10 мс.
Мы настраиваем Varnish под ключ для проектов с любой архитектурой — от медиа-сайтов до высоконагруженных API. В нашей практике есть кейсы с hit rate выше 95% и снижением нагрузки на backend на 80%. Один из проектов — интернет-магазин с 500 000 товаров — после внедрения Varnish сократил время загрузки карточек с 1 секунды до 30 мс, а ежемесячные расходы на облачные ресурсы снизились с $3000 до $500.
Заказчики получают не только конфигурацию, но и документацию по эксплуатации и обучение команды. В этой статье разберем типовые проблемы: неправильное кэширование кук, игнорирование grace-режима, отсутствие purge API.
Архитектура: Varnish перед nginx
Клиент → Varnish :80 → nginx :8080 → Backend :3000 Varnish не умеет завершать SSL, поэтому в продакшне перед ним ставят nginx или HAProxy для HTTPS терминации:
Клиент → nginx :443 (SSL termination) → Varnish :80 → nginx :8080 → Backend Или используют hitch — TLS proxy специально для связки с Varnish.
Почему Varnish, а не nginx cache?
Nginx — отличный веб-сервер и reverse proxy, но его кэш-система ограничена. Varnish спроектирован исключительно для кэширования: гибкий язык VCL, точное управление TTL, grace и stale-режимы, встроенный ban-механизм и детальная статистика. В проектах с hit rate ниже 90% и объёмом кэша больше 1 ГБ Varnish даёт выигрыш в скорости в 2-5 раз по сравнению с nginx.
| Характеристика | Varnish | nginx cache |
|---|---|---|
| Гибкость конфигурации | VCL — полный контроль | Ограниченные директивы |
| Hit rate | 85-98% | 70-80% типично |
| Grace/Stale | Да | Нет |
| Ban-механизм | Встроенный | Нет |
VCL: язык конфигурации
VCL (Varnish Configuration Language) — C-подобный язык, компилируется в нативный код при загрузке. Это даёт скорость, но требует понимания state machine Varnish: vcl_recv → vcl_hash → vcl_hit/vcl_miss → vcl_fetch → vcl_deliver.
Базовая конфигурация /etc/varnish/default.vcl
vcl 4.1;
import std;
backend default {
.host = "127.0.0.1";
.port = "8080";
.connect_timeout = 5s;
.first_byte_timeout = 60s;
.between_bytes_timeout = 30s;
}
sub vcl_recv {
# Убираем порт из Host для правильного кэш-ключа
set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");
# Не кэшируем POST, PUT, DELETE
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
# Не кэшируем авторизованные запросы
if (req.http.Authorization || req.http.Cookie ~ "session") {
return (pass);
}
# Убираем маркетинговые параметры из URL для лучшего hit rate
set req.url = regsuball(req.url, "([?&])(utm_[a-z]+|fbclid|gclid)=[^&]+", "\1");
set req.url = regsub(req.url, "[?&]$", "");
return (hash);
}
sub vcl_hash {
hash_data(req.url);
hash_data(req.http.Host);
# Разделяем кэш для mobile/desktop если нужно
if (req.http.X-Device-Type) {
hash_data(req.http.X-Device-Type);
}
return (lookup);
}
sub vcl_backend_response {
# Кэшируем 404 на 1 минуту чтобы не долбиться в бэкенд
if (beresp.status == 404) {
set beresp.ttl = 1m;
set beresp.grace = 30s;
}
# Grace period: отдаём устаревший кэш пока обновляется
set beresp.grace = 30s;
# Не кэшируем если бэкенд сказал no-cache
if (beresp.http.Cache-Control ~ "no-cache|no-store|private") {
set beresp.uncacheable = true;
set beresp.ttl = 120s;
return (deliver);
}
# По умолчанию кэшируем 10 минут
if (!beresp.http.Cache-Control) {
set beresp.ttl = 10m;
}
return (deliver);
}
sub vcl_deliver {
# Добавляем заголовок для дебага
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
set resp.http.X-Cache-Hits = obj.hits;
} else {
set resp.http.X-Cache = "MISS";
}
# Убираем внутренние заголовки Varnish
unset resp.http.X-Varnish;
unset resp.http.Via;
return (deliver);
}
Пример конфигурации для WordPress (аккордеон)
Для WordPress часто требуется исключить админку и ajax-запросы. Добавьте в vcl_recv:
if (req.url ~ "wp-admin|wp-login|ajax") { return (pass); } Пример кейса: интернет-магазин с 500 000 товаров
Клиент жаловался на медленную загрузку карточек товаров (более 1 секунды). Причина — кэш nginx не кэшировал ответы из-за куки сессии. Мы внедрили Varnish с правилом игнорирования сессионных кук для гостевых пользователей и настроили grace-период 30 секунд. Hit rate вырос с 45% до 93%, время ответа упало до 30 мс.
Как настроить Varnish для максимального hit rate?
Чтобы достичь hit rate 90%+, следуйте этим правилам:
- Очищайте URL от маркетинговых параметров (utm, fbclid).
- Игнорируйте сессионные куки для неавторизованных пользователей.
- Используйте гранулярные TTL: для статики — часы, для контента — минуты.
- Включите grace-режим, чтобы бэкенд не блокировал ответ при загрузке.
Как настроить Varnish: пошаговая инструкция
- Установите Varnish из репозитория (varnish-cache.org).
- Настройте бэкенд в default.vcl (хост и порт вашего веб-сервера).
- Определите правила vcl_recv: исключите POST, авторизованные запросы, административные URL.
- Настройте vcl_backend_response: TTL, grace, no-cache обработку.
- Добавьте поддержку PURGE: ACL и правило в vcl_recv.
- Включите мониторинг: varnishstat и интеграция с Prometheus.
Purge: принудительный сброс кэша
acl purge_acl {
"localhost";
"127.0.0.1";
"10.0.0.0"/8;
}
sub vcl_recv {
if (req.method == "PURGE") {
if (!client.ip ~ purge_acl) {
return (synth(405, "Not Allowed"));
}
return (purge);
}
}Сброс конкретного URL: curl -X PURGE http://localhost/api/products/123. Для массового сброса по паттерну используйте varnishadm ban req.url ~ "^/api/products".
Мониторинг
# Статистика в реальном времени
varnishstat
# Просмотр логов запросов
varnishlog -i ReqURL,RespStatus,ObjTTL
# Hit rate за последние 10 секунд
varnishstat -f MAIN.cache_hit,MAIN.cache_miss -1Целевой cache hit rate для медиа-сайтов и ecommerce — 85%+. Если ниже 60% — или много персонализированного контента, или куки слишком агрессивно блокируют кэширование. После внедрения Varnish мы также сократили расходы на CDN: в одном проекте экономия составила $1500 ежемесячно.
Процесс и сроки
| Этап | Срок |
|---|---|
| Аудит архитектуры и логики кэширования | 1 день |
| Проектирование и написание VCL | 2-3 дня |
| Интеграция с SSL (nginx/hitch) | 1 день |
| Настройка purge API и мониторинга | 1-2 дня |
| Документирование и обучение | 1 день |
Стоимость рассчитывается индивидуально после аудита — свяжитесь с нами, чтобы оценить проект. Получите консультацию инженера по ускорению веб-приложений.
Что входит в работу
- VCL-конфигурация, адаптированная под ваш проект
- Настройка purge API (ban-механизм по URL и паттернам)
- Интеграция с SSL (nginx или hitch)
- Мониторинг и алерты (Prometheus + Grafana дашборд)
- Документация по эксплуатации и регламент сброса кэша
- Обучение команды (1-2 часа)
- Гарантия на конфигурацию — 30 дней после ввода в эксплуатацию
Наш опыт и результаты
Мы работаем с Varnish более 5 лет, настроили кэш для проектов с нагрузкой до 50 000 RPS. Типовые результаты: hit rate 92-98%, снижение нагрузки на бэкенд на 80%, уменьшение среднего времени ответа с 200-400 мс до 5-20 мс. Все инженеры сертифицированы по Varnish и Kubernetes. Подробнее о VCL читайте в Varnish Book.
Типичные ошибки при настройке Varnish
- Кэширование всех URL: игнорирование POST, авторизованных запросов, административных панелей. Правильно: только GET/HEAD без сессии.
- Слишком большой TTL: для динамических сайтов (e-commerce) оптимально 1-10 минут.
- Отсутствие purge API: без ban-механизма сброс кэша становится ручной операцией.
- Игнорирование grace: при падении бэкенда Varnish должен отдавать устаревший кэш, иначе — ошибка.
Если ваш проект требует ускорения — свяжитесь с нами. Мы оценим архитектуру и предложим решение.







