Налаштування 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 повинен віддавати застарілий кеш, інакше — помилка.
Якщо ваш проект потребує прискорення — зв'яжіться з нами. Ми оцінимо архітектуру та запропонуємо рішення.







