VCL
VCL (от англ. Varnish Configuration Language) — предметно-ориентированный язык программирования, используемый для написания конфигураций политики кэширования и обработки HTTP-запросов в обратном прокси-сервере Varnish Cache. Язык позволяет определять, как Varnish должен обрабатывать входящие и исходящие HTTP-запросы, включая решения о кэшировании, модификации заголовков, перенаправлениях и вызове бэкенд-серверов. VCL компилируется в байт-код C и выполняется в виртуальной машине Varnish, что обеспечивает высокую производительность и гибкость настройки.
История
VCL был разработан в 2006 году норвежским программистом Полом-Хеннингом Кампом (Poul-Henning Kamp) в рамках проекта Varnish Cache, созданного для нужд норвежской газеты Verdens Gang. Основной целью было создание быстрого и гибкого инструмента для ускорения доставки веб-контента путём кэширования. До появления VCL конфигурация кэширующих прокси (например, Squid) требовала написания сложных скриптов на C или использования громоздких конфигурационных файлов. VCL предложил декларативный подход, где логика обработки запросов описывается в виде простых правил, что значительно упростило настройку.
Первая версия VCL (VCL 1.0) была выпущена вместе с Varnish 1.0 в 2006 году. Язык быстро приобрёл популярность в сообществе веб-разработчиков благодаря своей эффективности и простоте. В 2012 году, с выходом Varnish 3.0, VCL был существенно расширен: добавлена поддержка модулей (VMOD), что позволило подключать внешние библиотеки на C для выполнения сложных операций (например, работа с базами данных, шифрование). В 2018 году, с Varnish 6.0, появилась поддержка HTTP/2 и улучшенная обработка потоков.
Синтаксис и структура
VCL — это декларативный язык, не являющийся языком общего назначения. Он не поддерживает циклы, рекурсию или динамическое выделение памяти. Программа на VCL состоит из набора подпрограмм (subroutines), которые вызываются в определённые моменты обработки HTTP-запроса. Основные подпрограммы:
vcl_recv— вызывается при получении запроса от клиента. Здесь принимаются решения о кэшировании, проверке аутентификации, перенаправлениях.vcl_backend_fetch— вызывается перед отправкой запроса на бэкенд-сервер. Позволяет модифицировать запрос (например, добавить заголовки).vcl_backend_response— вызывается после получения ответа от бэкенда. Определяет, как долго кэшировать ответ, какие заголовки удалить.vcl_deliver— вызывается перед отправкой ответа клиенту. Позволяет изменить заголовки ответа (например, добавитьX-Cache).vcl_hit— вызывается, когда в кэше найден подходящий объект.vcl_miss— вызывается, когда объект не найден в кэше.
Каждая подпрограмма возвращает действие, которое определяет дальнейшую обработку: pass (пропустить кэширование), pipe (прямая передача данных), hash (вычисление ключа кэша), synth (возврат синтетического ответа), restart (перезапуск обработки).
Пример конфигурации
```vcl vcl 4.1;
backend default { .host = "127.0.0.1"; .port = "8080"; }
sub vcl_recv { if (req.url ~ "^/api/") { return (pass); } if (req.http.Cookie) { return (hash); } }
sub vcl_backend_response { set beresp.ttl = 1h; if (beresp.status == 404) { set beresp.ttl = 0s; } } ```
В этом примере:
- Определён бэкенд-сервер на localhost:8080.
- В
vcl_recvзапросы к/api/не кэшируются (pass), а запросы с cookie кэшируются (hash). - В
vcl_backend_responseдля всех ответов устанавливается время жизни (TTL) 1 час, кроме ответов с кодом 404, которые не кэшируются.
Классификация и типы данных
VCL поддерживает ограниченный набор типов данных:
- Строки — последовательности символов, заключаются в двойные кавычки. Поддерживается конкатенация (
+). - Целые числа — 32-битные знаковые числа.
- Логические значения —
trueиfalse. - Время — задаётся в секундах, минутах, часах, днях (например,
1h,30m). - Регулярные выражения — используются для сопоставления с шаблонами (например,
req.url ~ "/api/"). - ACL (Access Control List) — списки IP-адресов для ограничения доступа.
- Хэш-таблицы — встроенные структуры для хранения пар ключ-значение (например,
req.httpдля заголовков).
Язык не поддерживает массивы, объекты или пользовательские структуры. Всё взаимодействие с внешними данными осуществляется через модули VMOD.
Применение
VCL используется преимущественно для настройки кэширования и оптимизации веб-трафика. Основные сценарии:
- Ускорение веб-сайтов — кэширование статического контента (изображения, CSS, JS) и динамических страниц, которые редко изменяются.
- Балансировка нагрузки — распределение запросов между несколькими бэкенд-серверами на основе правил VCL.
- Защита от DDoS-атак — ограничение частоты запросов, блокировка подозрительных IP-адресов с помощью ACL.
- Модификация HTTP-заголовков — добавление, удаление или изменение заголовков (например,
X-Forwarded-For,Set-Cookie). - A/B-тестирование — перенаправление части пользователей на разные версии сайта на основе cookie или IP.
- Интеграция с системами управления контентом (CMS) — например, для WordPress или Drupal VCL позволяет кэшировать страницы для анонимных пользователей, очищая кэш при публикации нового контента.
Преимущества и недостатки
Преимущества
- Высокая производительность — VCL компилируется в байт-код C, что делает его быстрее интерпретируемых языков (например, Lua в Nginx).
- Гибкость — возможность тонкой настройки кэширования под конкретные требования.
- Простота — декларативный синтаксис позволяет быстро писать конфигурации без глубоких знаний программирования.
- Расширяемость — через VMOD можно подключать любые функции на C.
Недостатки
- Ограниченная функциональность — VCL не является языком общего назначения, что затрудняет реализацию сложной бизнес-логики.
- Кривая обучения для сложных сценариев — хотя базовые правила просты, отладка сложных конфигураций может быть трудоёмкой.
- Зависимость от Varnish — VCL работает только в среде Varnish Cache, что ограничивает его применение.
Интересные факты
- VCL не является языком сценариев в традиционном смысле: он не выполняется в рантайме, а компилируется в байт-код C при загрузке конфигурации. Это позволяет Varnish достигать скорости обработки до 1 миллиона запросов в секунду на одном сервере.
- В VCL нет оператора
if-elseв привычном виде — используется конструкцияif (condition) { ... } else { ... }, но без поддержкиelse if. Для множественных условий применяются вложенные блоки. - Язык не поддерживает комментарии в стиле C++ (
//), только блочные комментарии/ /. - В VCL 4.0 (выпущен в 2015 году) была введена поддержка
vcl_initиvcl_fini— подпрограмм, выполняющихся при загрузке и выгрузке конфигурации, что позволило инициализировать внешние ресурсы (например, подключения к базам данных).
Источники
- Varnish Cache Documentation — "VCL Reference" (Varnish Software, 2023)
- Kamp, P.-H. (2006). "Varnish: A High-Performance HTTP Accelerator" (Proceedings of the 2006 USENIX Annual Technical Conference)
- "Varnish Cache: A Practical Guide" — O'Reilly Media, 2012
- Официальный репозиторий Varnish Cache на GitHub (varnishcache/varnish-cache)
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →