VCL
Язык конфигурации Varnish
- Раздел руководства:
-
7
ОПИСАНИЕ
Язык VCL — это небольшой предметно-ориентированный язык, предназначенный для описания обработки запросов и политики кэширования документов для Varnish Cache.
При загрузке новой конфигурации процесс управления varnishd преобразует код VCL в C и компилирует его в общий объект, который затем загружается в процесс сервера.
Данный документ фокусируется на синтаксисе языка VCL. Полное описание синтаксиса и семантики с множеством примеров можно найти в онлайн-документации по адресу https://www.varnish-cache.org/docs/ .
Начиная с Varnish 4.0, каждый файл VCL должен начинаться с объявления своей версии с помощью маркера vcl <major>.<minor>; в верхней части файла. Подробнее об этом см. в разделе Версионирование.
Операторы
В VCL доступны следующие операторы:
-
= -
Оператор присваивания.
-
+, -, *, /, % -
Основные математические операции над числовыми значениями.
-
+=, -=, *=, /= -
Оператор присваивания с инкрементом/декрементом/умножением/делением.
Для строк
+=выполняется конкатенация. -
(, ) -
Вычисление по отдельности.
-
==, !=, <, >, <=, >= -
Сравнения
-
~, !~ -
Сопоставление/несопоставление. Может использоваться с регулярными выражениями или списками управления доступом (ACL).
-
! -
Отрицание.
-
&& / || -
Логическое И/ИЛИ.
Условные операторы
VCL имеет операторы if и else. Вложенную логику можно реализовать с помощью оператора elseif (elsif/elif/else if эквивалентны).
Обратите внимание, что в VCL нет циклов или итераторов любого типа.
Переменные
VCL выполняет большую часть работы, анализируя, set и unset переменные:
if (req.url == "/mistyped_url.html") {
set req.url = "/correct_url.html";
unset req.http.cookie;
}
Существуют очевидные ограничения на то, что можно сделать. Например, нет смысла unset req.url; — запрос должен иметь какой-то URL, чтобы быть корректным, и аналогично попытка манипулировать ответом бэкенда, когда его (еще) нет, бессмысленно. Компилятор VCL обнаружит такие ошибки.
Переменные имеют типы. Большинство из них — СТРОКИ, и всё в VCL может быть преобразовано в СТРОКУ, но некоторые переменные имеют типы, такие как DURATION, IP и т. д.
При установке таких переменных правая часть знака равенства должна иметь правильный тип переменной. Нельзя присвоить СТРОКУ переменной типа ЧИСЛО, даже если строка "42".
Функции явного преобразования доступны в VMOD std — стандартный модуль Varnish.
Полный список переменных VCL см.: VCL-Переменные.
Строки
Базовые строки заключены в двойные кавычки "…", и не могут содержать переводы строк. Длинные строки заключаются в {"…"} или """…""". Они могут содержать любые символы, включая одиночные двойные кавычки ", символы перевода строки и другие управляющие символы, кроме символа NUL (0x00).
Булевы значения
Булевы значения могут быть либо true либо false. Кроме того, в контексте булевых значений некоторые типы данных будут оцениваться как true или false в зависимости от их значения.
Строки будут оцениваться как false , если они не заданы. Это позволяет проверять, существует ли заголовок, даже если он пустой, например, if (req.http.opthdr) {}, в то время как if (req.http.opthdr == "") {} не различает, не существует ли заголовок или он пустой.
Типы бэкендов будут оцениваться как false , если им не назначен бэкенд; целочисленные типы будут оцениваться как false , если их значение равно нулю; типы интервалов времени будут оцениваться как false , если их значение равно или меньше нуля.
Время
VCL имеет время. К интервалу времени можно добавить длительность, чтобы получить другое время. В контексте строк они возвращают отформатированную строку в формате RFC1123, например, Sun, 06 Nov 1994 08:49:37 GMT.
Ключевое слово now возвращает текущее время, которое остается неизменным во время вызовов подпрограмм VCL, поэтому во время выполнения подпрограммы состояния VCL (vcl_* {}), включая все вызываемые пользовательские подпрограммы, now всегда возвращает одно и то же значение.
Продолжительности
Длительности определяются числом, за которым следует единица измерения. Число может включать дробную часть, например 1.5s. Поддерживаемые единицы измерения:
-
ms -
миллисекунды
-
s -
секунды
-
m -
минуты
-
h -
часы
-
d -
дни
-
w -
недели
-
y -
годы
В контексте строк они возвращают строку со своим значением, округлённым до 3 знаков после запятой, без единицы измерения, например 1.500.
Целые числа
Некоторые поля — целые числа, используемые как ожидается. В контексте строк они возвращают строку, например 1234.
Вещественные числа
VCL понимает вещественные числа. В контексте строк они возвращают строку со своим значением, округлённым до 3 знаков после запятой, например 3.142.
Регулярные выражения
Varnish использует Perl-совместимые регулярные выражения (PCRE). Полное описание см. в справке man pcre(3).
Для передачи флагов движку PCRE, например, для выполнения сопоставления без учёта регистра, добавьте флаг в скобки после вопросительного знака, например:
# If host is NOT example dot com..
if (req.http.host !~ "(?i)example\.com$") {
...
}
Инструкция include
Для включения файла VCL в другой файл используйте ключевое слово include:
include "foo.vcl";
Необязательно, ключевое слово include может принимать флаг +glob для включения всех файлов, соответствующих шаблону glob:
include +glob "example.org/*.vcl";
Инструкция import
Инструкция import используется для загрузки модулей Varnish (VMOD).
Пример:
import std;
sub vcl_recv {
std.log("foo");
}
Бэкенды и тесты работоспособности
См. VCL-бэкенды и VCL-проверка
Список управления доступом (ACL)
Декларация списка управления доступом (ACL) создаёт и инициализирует именованный список управления доступом, который можно использовать для сопоставления адресов клиентов:
acl localnetwork {
"localhost"; # myself
"192.0.2.0"/24; # and everyone on the local network
! "192.0.2.23"; # except for the dial-in router
}
Если запись ACL указывает имя хоста, которое Varnish не может разрешить, она будет соответствовать любому адресу, с которым она сравнивается. Следовательно, если ей предшествует знак отрицания, она отклонит любой адрес, с которым она сравнивается, что может быть не тем, что вы имели в виду. Однако, если запись заключена в скобки, она просто будет проигнорирована, если имя хоста не может быть разрешено.
Для сопоставления IP-адреса со списком управления доступом (ACL) просто используйте оператор сопоставления:
if (client.ip ~ localnetwork) {
return (pipe);
}
ACL имеют флаги функций, которые можно устанавливать или сбрасывать для каждого ACL индивидуально:
-
+log— Вывести записьAclв VSL, чтобы указать, было ли найдено соответствие или нет. -
+table— Реализовать ACL с помощью таблицы вместо скомпилированного кода. Это работает немного медленнее, но компилирует большие ACL намного быстрее. -
-pedantic— Разрешить маски для покрытия не нулевых битов хоста. Это позволяет работать следующему:acl foo -pedantic +log { "firewall.example.com" / 24; }Однако, если имя резолвется как IPv4 и IPv6, вы по-прежнему получите ошибку.
Объекты VCL
Объект VCL можно создать с помощью ключевого слова new:
sub vcl_init {
new b = directors.round_robin()
b.add_backend(node1);
}
Это доступно только в vcl_init.
Подпрограммы
Подпрограмма используется для группирования кода для лучшей читаемости или повторного использования:
sub pipe_if_local {
if (client.ip ~ localnetwork) {
return (pipe);
}
}
Подпрограммы в VCL не принимают аргументы и не возвращают значения. Встроенные подпрограммы имеют имена, начинающиеся с vcl_, что зарезервировано.
Для вызова подпрограммы используйте ключевое слово call за которым следует имя подпрограммы:
sub vcl_recv {
call pipe_if_local;
}
Инструкции return
Выполнение текущей подпрограммы vcl_* завершается, когда выполняется инструкция return(<действие>).
<действие> определяет, как должно продолжаться выполнение. Контекст определяет доступные действия.
Возможно завершение подпрограммы, которая не является встроенной, с помощью простой инструкции return без указания действия. Это завершает подпрограмму без перехода в другое состояние:
sub filter_cookies {
if (!req.http.cookie) {
return;
}
# complex cookie filtering
}
Много подпрограмм
Если определено несколько подпрограмм с именем одной из встроенных, они конкатенируются в порядке их появления в исходном коде.
Встроенные подпрограммы VCL, поставляемые с Varnish, будут неявно конкатенированы при компиляции VCL.
Функции
Доступны следующие встроенные функции:
ban(STRING)
Устаревшая. См. BOOL ban(STRING).
Функция ban() идентична BOOL ban(STRING), но не обеспечивает отчёт об ошибках.
hash_data(input)
Добавляет входные данные в хэш. Во встроенном VCL hash_data() вызывается на хосте и URL запроса. Доступно в vcl_hash.
synthetic(STRING)
Подготавливает синтезированное тело ответа, содержащее STRING. Доступно в vcl_synth и vcl_backend_error.
Идентично set resp.body / set beresp.body.
regsub(str, regex, sub)
Возвращает копию str с первой заменой вхождения регулярного выражения regex на sub. Внутри sub, \0 (которое также можно написать как \&) заменяется на всю совпавшую строку, а \n заменяется на содержимое подгруппы n в совпавшей строке.
regsuball(str, regex, sub)
Как regsub(), но заменяет все вхождения.
Для преобразования или приведения значений VCL между типами данных используйте функции, доступные в модуле std VMOD.
Версии
Несколько версий синтаксиса VCL могут сосуществовать в определённых ограничениях.
Версия синтаксиса VCL в начале файла VCL, указанная -f, устанавливает жёсткое ограничение, которого нельзя превысить, и выбирает соответствующую версию встроенного VCL.
Это означает, что вы не можете включить vcl 9.1; из vcl 8.7;, но обратное может быть возможным, в той мере, в которой это поддерживается компилятором.
Файлы, подключённые через include не должны иметь vcl X.Y;, но всё же неплохо это сделать, чтобы избежать неожиданностей в будущем. Версия синтаксиса, установленная в включаемом файле, применяется только к этому файлу и любым файлам, которые он включает — если эти файлы не установят свою собственную версию синтаксиса VCL.
Версия Varnish, к которой принадлежит этот файл, поддерживает синтаксис 4.0 и 4.1.
ПРИМЕРЫ
Примеры см. в онлайн-документации.
СМОТРИТЕ ТАКЖЕ
ИСТОРИЯ
VCL был разработан Poul-Henning Kamp в сотрудничестве с Verdens Gang AS, Redpill Linpro и Varnish Software. Эта страница руководства написана Per Buer, Poul-Henning Kamp, Martin Blix Grydeland, Kristian Lyngstøl, Lasse Karstensen и другими.
АВТОРСКИЕ ПРАВА
Этот документ лицензирован по той же лицензии, что и сам Varnish. Подробности см. в файле LICENSE.
- Авторское право (c) 2006 Verdens Gang AS
- Авторское право (c) 2006-2015 Varnish Software AS
Copyright © 2006 Verdens Gang AS
Copyright © 2006–2020 Varnish Software AS
Licensed under the BSD-2-Clause License.
https://varnish-cache.org/docs/7.4/reference/vcl.html
Комментарии
Одиночные строки VCL можно прокомментировать, используя
//или#. Многострочные блоки можно прокомментировать с помощью/*блок*/.Пример:
sub vcl_recv { // Single line of out-commented VCL. # Another way of commenting out a single line. /* Multi-line block of commented-out VCL. */ }