- Home »

Ускорение статических веб-страниц с Varnish Cache на Ubuntu 24
Если вы хотите получить максимальную скорость отдачи статических веб-страниц и чувствуете, что nginx или Apache сами по себе не вытягивают нагрузку, то эта статья для вас. Мы разберём как настроить Varnish Cache на Ubuntu 24 — мощный HTTP-акселератор, который способен превратить ваш сайт в скоростного монстра. Покажу конкретные шаги, реальные примеры конфигураций и расскажу о подводных камнях, которые могут сожрать ваше время.
Varnish умеет кэшировать HTTP-запросы на уровне, который заставит ваш сайт летать. Средняя скорость отдачи кэшированного контента может вырасти в 10-100 раз, а нагрузка на бэкенд сервер упадёт в разы. Это особенно критично для высоконагруженных проектов, где каждая миллисекунда на счету.
Как работает Varnish Cache
Varnish — это reverse proxy cache, который сидит между пользователем и вашим веб-сервером. При первом запросе к странице Varnish запрашивает её у бэкенда (nginx/Apache), сохраняет в памяти и при следующих запросах отдаёт готовый результат без обращения к серверу.
Основные принципы работы:
- Кэширование в RAM — весь кэш хранится в оперативной памяти, что обеспечивает максимальную скорость
- VCL (Varnish Configuration Language) — собственный язык для гибкой настройки логики кэширования
- Hit/Miss механизм — если контент есть в кэше (hit), отдаём его, если нет (miss) — запрашиваем у бэкенда
- TTL (Time To Live) — время жизни кэшированного объекта
- Purging — принудительное удаление объектов из кэша
Установка Varnish на Ubuntu 24
Начнём с установки. Ubuntu 24 поставляется с достаточно свежей версией Varnish в репозиториях:
sudo apt update
sudo apt install varnish
# Проверяем версию
varnish -V
# Запускаем и добавляем в автозагрузку
sudo systemctl enable varnish
sudo systemctl start varnish
Если нужна самая свежая версия, можно поставить из официального репозитория:
curl -fsSL https://packagecloud.io/varnishcache/varnish70/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/varnish-cache.gpg
echo "deb [signed-by=/usr/share/keyrings/varnish-cache.gpg] https://packagecloud.io/varnishcache/varnish70/ubuntu/ noble main" | sudo tee /etc/apt/sources.list.d/varnish-cache.list
sudo apt update
sudo apt install varnish
Базовая конфигурация
По умолчанию Varnish слушает порт 6081, а ваш веб-сервер должен работать на другом порту (например, 8080). Начнём с настройки nginx:
# Редактируем конфиг nginx
sudo nano /etc/nginx/sites-available/default
# Меняем порт с 80 на 8080
server {
listen 8080 default_server;
listen [::]:8080 default_server;
# остальная конфигурация...
}
# Перезапускаем nginx
sudo systemctl reload nginx
Теперь настраиваем Varnish для работы на 80 порту:
# Редактируем systemd unit
sudo nano /etc/systemd/system/varnish.service
[Unit]
Description=Varnish HTTP accelerator
Documentation=https://www.varnish-cache.org/docs/
After=network.target
[Service]
Type=exec
ExecStart=/usr/sbin/varnishd -a :80 -f /etc/varnish/default.vcl -s malloc,1g
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
# Перезагружаем systemd и перезапускаем
sudo systemctl daemon-reload
sudo systemctl restart varnish
Конфигурация VCL
Самое интересное — настройка VCL. Создаём базовый конфиг для статики:
sudo nano /etc/varnish/default.vcl
vcl 4.1;
# Бэкенд - наш nginx
backend default {
.host = "127.0.0.1";
.port = "8080";
.connect_timeout = 5s;
.first_byte_timeout = 60s;
.between_bytes_timeout = 60s;
}
# Настройка входящих запросов
sub vcl_recv {
# Удаляем порт из Host header
set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");
# Не кэшируем POST, PUT, DELETE
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
# Убираем ненужные заголовки для лучшего кэширования
unset req.http.Cookie;
unset req.http.Authorization;
# Нормализация URL
set req.url = regsuball(req.url, "\?.*$", "");
return (hash);
}
# Настройка ответов от бэкенда
sub vcl_backend_response {
# Кэшируем статику надолго
if (bereq.url ~ "\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$") {
set beresp.ttl = 1h;
set beresp.http.Cache-Control = "public, max-age=3600";
}
# HTML кэшируем на меньшее время
if (beresp.http.Content-Type ~ "text/html") {
set beresp.ttl = 5m;
set beresp.http.Cache-Control = "public, max-age=300";
}
# Убираем Set-Cookie для статики
if (bereq.url ~ "\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$") {
unset beresp.http.Set-Cookie;
}
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";
}
set resp.http.X-Served-By = server.hostname;
return (deliver);
}
Проверяем конфигурацию и перезапускаем:
# Проверяем VCL на ошибки
sudo varnishd -C -f /etc/varnish/default.vcl
# Перезапускаем Varnish
sudo systemctl restart varnish
Мониторинг и отладка
Varnish поставляется с отличными утилитами для мониторинга:
# Статистика в реальном времени
varnishstat
# Лог запросов
varnishlog
# Топ запросов
varnishtop
# Просмотр кэша
varnishadm
# > ban.list
# > storage.list
Для мониторинга hit rate создадим простой скрипт:
#!/bin/bash
# /usr/local/bin/varnish-stats.sh
echo "=== Varnish Cache Statistics ==="
echo "Hit Rate: $(varnishstat -1 | grep MAIN.cache_hit_rate | awk '{print $2}')%"
echo "Cache Hits: $(varnishstat -1 | grep MAIN.cache_hit | awk '{print $2}')"
echo "Cache Misses: $(varnishstat -1 | grep MAIN.cache_miss | awk '{print $2}')"
echo "Objects in Cache: $(varnishstat -1 | grep MAIN.n_object | awk '{print $2}')"
echo "Memory Usage: $(varnishstat -1 | grep SMA.s0.g_bytes | awk '{print $2/1024/1024}') MB"
Продвинутые настройки
Для высоконагруженных сайтов можно использовать более сложные конфигурации:
# Настройка для работы с несколькими бэкендами
backend web1 {
.host = "10.0.0.10";
.port = "80";
.probe = {
.url = "/health";
.interval = 5s;
.timeout = 1s;
.window = 5;
.threshold = 3;
}
}
backend web2 {
.host = "10.0.0.11";
.port = "80";
.probe = {
.url = "/health";
.interval = 5s;
.timeout = 1s;
.window = 5;
.threshold = 3;
}
}
# Балансировщик нагрузки
sub vcl_init {
new vdir = directors.round_robin();
vdir.add_backend(web1);
vdir.add_backend(web2);
}
sub vcl_recv {
set req.backend_hint = vdir.backend();
}
Управление кэшем
Для принудительной очистки кэша настроим purging:
# Добавляем в vcl_recv
sub vcl_recv {
# Purge запросы только с локального хоста
if (req.method == "PURGE") {
if (!client.ip ~ purge_acl) {
return (synth(405, "Method not allowed"));
}
return (purge);
}
}
# ACL для purge
acl purge_acl {
"127.0.0.1";
"::1";
"10.0.0.0/8";
}
# Скрипт для очистки кэша
#!/bin/bash
# /usr/local/bin/purge-cache.sh
URL=${1:-".*"}
curl -X PURGE "http://localhost/$URL"
echo "Cache purged for: $URL"
Сравнение с альтернативами
Решение | Скорость | Память | Гибкость | Сложность |
---|---|---|---|---|
Varnish | Очень высокая | Только RAM | Очень гибкий | Средняя |
Nginx proxy_cache | Высокая | Диск + RAM | Ограниченная | Низкая |
Apache mod_cache | Средняя | Диск + RAM | Ограниченная | Низкая |
Squid | Средняя | Диск + RAM | Высокая | Высокая |
Интеграция с системами мониторинга
Для интеграции с Prometheus создадим экспортер метрик:
# Установка varnish_exporter
wget https://github.com/jonnenauha/prometheus_varnish_exporter/releases/download/1.6.1/prometheus_varnish_exporter-1.6.1.linux-amd64.tar.gz
tar -xzf prometheus_varnish_exporter-1.6.1.linux-amd64.tar.gz
sudo cp prometheus_varnish_exporter-1.6.1.linux-amd64/prometheus_varnish_exporter /usr/local/bin/
# Systemd сервис
sudo nano /etc/systemd/system/varnish-exporter.service
[Unit]
Description=Varnish Exporter
After=network.target
[Service]
Type=simple
User=varnish
ExecStart=/usr/local/bin/prometheus_varnish_exporter
Restart=always
[Install]
WantedBy=multi-user.target
sudo systemctl enable varnish-exporter
sudo systemctl start varnish-exporter
Автоматизация и скрипты
Создадим полезные скрипты для автоматизации:
#!/bin/bash
# /usr/local/bin/varnish-warmup.sh
# Прогрев кэша после деплоя
SITEMAP_URL="https://example.com/sitemap.xml"
CONCURRENT=10
echo "Starting cache warmup..."
curl -s "$SITEMAP_URL" | grep -oP '(?<=).*?(?= )' | \
xargs -n 1 -P $CONCURRENT -I {} curl -s -o /dev/null -w "%{url_effective}: %{time_total}s\n" {}
echo "Cache warmup completed!"
#!/bin/bash
# /usr/local/bin/varnish-health.sh
# Проверка состояния Varnish
THRESHOLD=80
HIT_RATE=$(varnishstat -1 | grep MAIN.cache_hit_rate | awk '{print $2}' | cut -d. -f1)
if [ "$HIT_RATE" -lt "$THRESHOLD" ]; then
echo "WARNING: Hit rate is $HIT_RATE% (threshold: $THRESHOLD%)"
# Отправляем уведомление или перезапускаем
# systemctl restart varnish
else
echo "OK: Hit rate is $HIT_RATE%"
fi
Продвинутые кейсы использования
Несколько интересных сценариев:
- API кэширование — кэшируем GET запросы к API с коротким TTL
- Геолокация — разный контент для разных стран через VCL
- A/B тестирование — распределение трафика между версиями
- Защита от DDoS — rate limiting на уровне VCL
Пример защиты от флуда:
import std;
import vsthrottle;
sub vcl_recv {
# Ограничиваем до 10 запросов в секунду с IP
if (vsthrottle.is_denied(client.ip, 10, 1s)) {
return (synth(429, "Too Many Requests"));
}
}
Типичные ошибки и решения
- Кэширование динамического контента — всегда проверяйте что кэшируете
- Недостаток памяти — следите за размером кэша и настраивайте LRU
- Проблемы с SSL — Varnish не умеет SSL, используйте nginx или HAProxy перед ним
- Кэширование с куками — обязательно убирайте ненужные куки
Масштабирование
Для больших проектов рекомендую рассмотреть VPS с достаточным объёмом RAM или выделенный сервер для максимальной производительности.
Схема для высоконагруженного сайта:
- Load Balancer (HAProxy/nginx) → SSL termination
- Varnish кластер → кэширование
- Web серверы → обработка запросов
- Database → данные
Заключение и рекомендации
Varnish — это мощный инструмент для ускорения веб-сайтов, который может дать прирост производительности в десятки раз. Основные рекомендации:
- Используйте для статики и редко меняющегося контента — здесь Varnish показывает максимальную эффективность
- Выделите достаточно RAM — весь кэш должен помещаться в памяти
- Тщательно настройте VCL — от этого зависит hit rate
- Мониторьте производительность — следите за hit rate и временем ответа
- Автоматизируйте управление — создайте скрипты для purge и warmup
Varnish идеально подходит для:
- Новостных сайтов и блогов
- Интернет-магазинов (страницы товаров)
- API с предсказуемыми запросами
- Любых высоконагруженных проектов
Не используйте Varnish для:
- Персонализированного контента
- Сайтов с активным использованием POST запросов
- Проектов с ограниченным объёмом RAM
Правильно настроенный Varnish может снизить нагрузку на ваши серверы в разы и значительно улучшить пользовательский опыт. Экспериментируйте с конфигурацией, мониторьте метрики и не забывайте про безопасность!
В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.
Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.