Открыть сервис

Varnish Configuration Language

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

История и предпосылки создания

Varnish Cache был разработан датским программистом Поулем-Хеннингом Кампом (Poul-Henning Kamp) для норвежской газеты Verdens Gang. Первая версия вышла в 2006 году. Основной задачей Varnish было эффективное кэширование динамического веб-контента, особенно для сайтов с высокой посещаемостью. Для описания логики кэширования требовался гибкий и производительный инструмент, который не был бы привязан к конкретному веб-серверу или языку сценариев (как mod_rewrite для Apache). Так появился VCL. Идея заключалась в том, чтобы администратор мог писать правила на специализированном высокоуровневом языке, который затем транслировался бы в эффективный машинный код, а не интерпретировался на лету. Первая стабильная версия VCL была представлена вместе с Varnish 1.0.

Синтаксис и структура

Синтаксис VCL напоминает синтаксис языков C и Perl. Он использует фигурные скобки для обозначения блоков кода, точку с запятой для завершения операторов и операторы if/else для ветвления. Ключевой особенностью VCL является его событийно-ориентированная структура. Вместо линейного выполнения кода, VCL определяет набор подпрограмм (subroutines), которые вызываются Varnish на определённых этапах обработки запроса.

Основные подпрограммы (субрутины)

VCL определяет несколько встроенных субрутин, которые являются точками входа для кода администратора. Наиболее важные из них:

  • vcl_recv: Вызывается в начале обработки запроса. Используется для принятия решений на основе входящего запроса: нужно ли его кэшировать, нужно ли его обслуживать напрямую с бэкенда, нужно ли его перенаправить. Здесь можно изменять или удалять заголовки запроса.
  • vcl_hash: Определяет, как формируется ключ кэша для данного запроса. По умолчанию ключ состоит из URL и хоста, но его можно модифицировать, например, добавляя в него определённые заголовки (Cookie, User-Agent) или исключая их.
  • vcl_hit: Вызывается, когда объект найден в кэше (cache hit). Здесь можно решить, отдавать ли объект из кэша или, например, проверить его актуальность.
  • vcl_miss: Вызывается, когда объект не найден в кэше (cache miss). Здесь можно решить, отправлять ли запрос на бэкенд, или, например, попытаться найти объект в другом месте.
  • vcl_pass: Вызывается, когда запрос не должен кэшироваться (например, после вызова return(pass) в vcl_recv). Запрос передаётся на бэкенд, а ответ не кэшируется.
  • vcl_fetch (в Varnish 3.x) / vcl_backend_response (в Varnish 4.x+): Вызывается после получения ответа от бэкенда. Используется для модификации ответа перед его кэшированием или передачей клиенту. Здесь можно устанавливать TTL, изменять заголовки ответа, решать, нужно ли кэшировать этот объект.
  • vcl_deliver: Вызывается перед отправкой ответа клиенту. Используется для финальной модификации заголовков ответа (например, для добавления заголовка X-Cache: HIT или X-Cache: MISS).
  • vcl_error: Вызывается в случае ошибки (например, когда бэкенд недоступен). Позволяет вернуть пользовательскую страницу ошибки.

Типы данных и операторы

VCL поддерживает основные типы данных: строки (string), целые числа (integer), числа с плавающей точкой (float), логические значения (boolean), а также специальные типы, такие как DURATION (время, например, 1h, 30s), TIME (абсолютное время), HEADER (заголовок HTTP) и IP (IP-адрес). Операторы включают арифметические (+, -, *, /), сравнения (==, !=, >, <, >=, <=), логические (&&, ||, !), а также оператор конкатенации строк (+). Для доступа к заголовкам HTTP используется синтаксис req.http.ИмяЗаголовка (для запроса) и beresp.http.ИмяЗаголовка (для ответа бэкенда) или resp.http.ИмяЗаголовка (для ответа клиенту).

Пример использования

Ниже приведён пример простого VCL-файла, который демонстрирует базовые возможности:

```vcl vcl 4.1;

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

sub vcl_recv {

Удаляем Cookie для статических файлов, чтобы они кэшировались

if (req.url ~ "\.(png|gif|jpg|jpeg|css|js|ico)$") { unset req.http.Cookie; }

Не кэшируем запросы к административной панели

if (req.url ~ "^/admin") { return(pass); }

Не кэшируем POST-запросы

if (req.method == "POST") { return(pass); } }

sub vcl_backend_response {

Устанавливаем TTL для статических файлов в 1 час

if (bereq.url ~ "\.(png|gif|jpg|jpeg|css|js|ico)$") { set beresp.ttl = 1h; }

Не кэшируем ответы с ошибками

if (beresp.status >= 500) { set beresp.uncacheable = true; } }

sub vcl_deliver {

Добавляем заголовок, указывающий, был ли ответ из кэша

if (obj.hits > 0) { set resp.http.X-Cache = "HIT"; } else { set resp.http.X-Cache = "MISS"; } } ```

Компиляция и загрузка

VCL-код не интерпретируется напрямую. Когда администратор загружает новый VCL-файл (обычно с помощью команды varnishadm или varnish_reload_vcl), Varnish Cache компилирует его в C-код, который затем компилируется в разделяемую библиотеку (shared object) с помощью стандартного компилятора C (обычно GCC или Clang). Эта библиотека динамически загружается в работающий процесс Varnish. Такой подход обеспечивает скорость выполнения правил, сравнимую с нативным кодом, и позволяет менять конфигурацию без перезапуска всего сервера.

Версии VCL

VCL развивался вместе с Varnish Cache. Версия VCL указывается в начале файла (директива vcl 4.1;). Основные различия между версиями:

  • VCL 2.x (Varnish 2.x): Базовая версия, включала субрутины vcl_recv, vcl_fetch, vcl_deliver, vcl_error, vcl_hit, vcl_miss, vcl_pass.
  • VCL 3.x (Varnish 3.x): Добавлены улучшения, такие как поддержка return(synth) для генерации синтетических ответов, и более строгая типизация.
  • VCL 4.0 (Varnish 4.0): Значительное обновление. Субрутина vcl_fetch была переименована в vcl_backend_response. Введены новые субрутины, такие как vcl_synth (для обработки синтетических ответов) и vcl_pipe. Изменён синтаксис некоторых операций (например, return(pass) стал return(pass) для запроса и return(deliver) для ответа).
  • VCL 4.1 (Varnish 4.1+): Добавлена поддержка vcl_init и vcl_fini для инициализации и завершения работы VCL-модулей, а также возможность использования import для подключения сторонних модулей (VMODs).

VMODs (Varnish Modules)

VCL является достаточно мощным языком, но его возможности могут быть расширены с помощью VMODs (Varnish Modules). VMODs — это динамические библиотеки, написанные на C (или другом языке, который может быть скомпилирован в разделяемую библиотеку), которые предоставляют новые функции для использования в VCL. Например, существуют VMODs для работы с регулярными выражениями, для обработки cookie, для работы с GeoIP, для интеграции с различными базами данных и т.д. Для использования VMOD его необходимо импортировать в VCL-файле с помощью директивы import.

Критика и ограничения

Несмотря на свою эффективность, VCL имеет некоторые ограничения и критикуется за:

  • Сложность отладки: Поскольку VCL компилируется в C, отладка ошибок может быть затруднена. Сообщения об ошибках компиляции часто ссылаются на сгенерированный C-код, что может быть неочевидно для администратора.
  • Отсутствие циклов и сложных структур данных: VCL не поддерживает циклы (for, while) и сложные структуры данных, такие как массивы или хэш-таблицы. Это делает его непригодным для написания сложной логики. Для таких задач рекомендуется использовать VMODs или внешние сервисы.
  • Строгая типизация: VCL является строго типизированным языком, что может вызывать ошибки при попытке выполнить недопустимые операции с типами (например, сложить строку и число).
  • Ограниченная документация: Документация по VCL, особенно по новым функциям и VMODs, иногда может быть неполной или устаревшей.

Применение

VCL является основным инструментом для настройки Varnish Cache. Он используется для:

  • Управления кэшированием (установка TTL, инвалидация кэша).
  • Фильтрации и модификации HTTP-заголовков.
  • Перенаправления запросов (редиректы).
  • Балансировки нагрузки между несколькими бэкендами.
  • Обработки ошибок и возврата пользовательских страниц.
  • Реализации сложных правил доступа и аутентификации.
  • Интеграции с системами мониторинга и аналитики.

Источники

  • Varnish Cache Documentation. "VCL (Varnish Configuration Language)". Varnish Software.
  • Kamp, Poul-Henning. "Varnish Cache: A High-Performance HTTP Accelerator". ACM Queue, 2006.
  • Varnish Software. "Varnish Reference Manual". Varnish Software.
  • "Varnish Cache 4.0: What's New". Varnish Software Blog.

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →