Home » Ускорение статических веб-страниц с Varnish Cache на Ubuntu 24
Ускорение статических веб-страниц с Varnish Cache на Ubuntu 24

Ускорение статических веб-страниц с 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 может снизить нагрузку на ваши серверы в разы и значительно улучшить пользовательский опыт. Экспериментируйте с конфигурацией, мониторьте метрики и не забывайте про безопасность!


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

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

Leave a reply

Your email address will not be published. Required fields are marked