VCL¶
Varnish配置语言¶
- 手册部分:
7
DESCRIPTION¶
VCL语言是一种特定于领域的小型语言,旨在用于描述Varnish缓存的请求处理和文档缓存策略。
当加载新配置时,varnishd管理进程将VCL代码转换为C,并将其编译为共享对象,然后将其加载到服务器进程中。
本文档重点介绍VCL语言的语法。有关语法和语义的完整描述以及大量示例,请参阅https://www.varnish-cache.org/docs/上的在线文档。
Starting with Varnish 4.0, each VCL file must start by declaring its
version with vcl
<major>.<minor>;
marker at the top of
the file. See more about this under Versioning below.
操作员¶
VCL中提供以下运算符:
=
赋值操作符。
+
,-
,*
,/
,%
关于数值的基本数学。
+=
,-=
,*=
,/=
赋值和递增/递减/乘/除运算符。
对于字符串,
+=
附加。(
,)
单独评估。
==
,!=
,<
,>
,<=
,>=
比较
~
,!~
匹配/不匹配。可以与正则表达式或ACL一起使用。
!
否定。
&&
/||
逻辑与/或。
条件句¶
VCL has if
and else
statements. Nested logic can be
implemented with the elseif
statement (elsif
/elif
/else if
are equivalent).
请注意,VCL中没有任何类型的循环或迭代器。
变数¶
VCL通过检查来完成大部分工作, set
ING和‘ unset
‘ING变量::
if (req.url == "/mistyped_url.html") {
set req.url = "/correct_url.html";
unset req.http.cookie;
}
可以做的事情有明显的局限性,例如,它没有意义 unset req.url;
-请求必须有某种类型的URL才能有效,同样地,在没有URL的情况下试图操纵后端响应也是没有意义的。VCL编译器将检测到此类错误。
变量有类型。大多数变量都是字符串,VCL中的任何内容都可以转换为字符串,但一些变量的类型如下 DURATION
, IP
等。
设置此类变量时,等号右侧必须具有正确的变量类型,不能将字符串赋给类型为NUMBER的变量,即使该字符串是 "42"
。
中提供了显式转换函数 VMOD标准-Varnish标准模块 。
有关VCL变量的完整专辑,请参阅: VCL-变量 。
弦¶
Basic strings are enclosed in double quotes "
..."
, and
may not contain newlines. Long strings are enclosed in
{"
..."}
or """
..."""
. They may contain any
character including single double quotes "
, newline and other control
characters except for the NUL (0x00) character.
布尔人¶
布尔型可以是 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)。有关完整说明,请参阅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
包括与全局模式匹配的所有文件的标志::
include +glob "example.org/*.vcl";
IMPORT语句¶
这个 import
语句用于加载Varnish模块(VMOD)。
示例::
import std;
sub vcl_recv {
std.log("foo");
}
后端和健康探测¶
访问控制列表(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,您仍会收到错误。
+fold -折叠ACL超网和相邻网络。
将此参数设置为ON时,将优化ACL,因为跳过其他条目中包含的子网(例如,如果1.2.3.0/24是ACL的一部分,则不会添加1.2.3.128/25的条目),并且折叠相邻条目(例如,如果同时添加1.2.3.0/25和1.2.3.128/25,则它们将合并到1.2.3.0/24)。
在VCL编译期间,对VCL条目的跳过和折叠操作作为警告输出,因为来自VCL的条目是按顺序处理的。
在下登录
VCL_acl
启用此参数后,标签可以更改:跳过的子网条目上的匹配现在记录为相应超网条目上的匹配。折叠条目上的匹配使用较短的网络掩码记录,该网络掩码可能不包含在VCL中定义的原始ACL中。这样的日志条目由fixed: folded
。否定的ACL条目永远不会折叠。
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;
}
返回报表¶
正在进行的 vcl_*
时,子例程执行结束 return(
<action> )
声明已经发表。
这个 <action> 指定应如何继续执行。上下文定义了哪些操作可用。
可以退出不属于内置子例程的子例程 return
语句,但不指定操作。它退出子例程,而不会转换到其他状态::
sub filter_cookies {
if (!req.http.cookie) {
return;
}
# complex cookie filtering
}
多个子例程¶
如果定义了多个子例程,并且这些子例程的名称与其中一个内置例程的名称相同,则它们将按照它们在源代码中出现的顺序连接在一起。
编译VCL时,将隐式串联随Varnish分发的内置VCL。
功能¶
以下内置函数可用:
BAN(字符串)¶
已弃用。看见 Bool BAN(字符串) 。
这个
ban()
函数与 Bool BAN(字符串) ,但不提供错误报告。
HASH_DATA(输入)¶
将输入添加到哈希输入。在内置的VCL中
hash_data()
在请求的主机和URL上调用。在以下位置可用vcl_hash
。
合成(细绳)¶
制备合成反应体,其中包含 STRING 。在以下位置可用
vcl_synth
和vcl_backend_error
。等同于
set resp.body
/set beresp.body
。
RegSub(字符串、正则表达式、SUB)¶
Returns a copy of str with the first occurrence of the regular expression regex replaced with sub. Within sub,
\0
(which can also be spelled\&
) is replaced with the entire matched string, and\
n is replaced with the contents of subgroup n in the matched string.
Regsuball(字符串、正则表达式、SUB)¶
AS
regsub()
,但这将替换所有出现的项。
要在数据类型之间转换或转换VCL值,请使用STD VMOD中提供的函数。
版本化¶
多个版本的VCL语法可以在某些约束内共存。
指定的VCL文件开头的VCL语法版本 -f
设置不能在任何地方超过的硬限制,并选择适当版本的内置VCL。
这意味着你永远不能包括 vcl 9.1;
从… vcl 8.7;
,但恰恰相反 may 在编译器支持的范围内,是可能的。
Files pulled in via include
do not need to have a
vcl
X.Y;
but it may be a good idea to do it anyway, to
not have surprises in the future. The syntax version set in an
included file only applies to that file and any files it includes -
unless these set their own VCL syntax version.
此文件所属的Varnish版本支持语法4.0和4.1。
EXAMPLES¶
有关示例,请参阅在线文档。
另请参阅¶
HISTORY¶
VCL是由Pul-Henning Kamp与Verden Gang AS、Redpill Linpro和Varnish Software合作开发的。本手册页面由Per Buer、Pul-Henning Kamp、Martin Blix Grydeland、Kristian LyngstøL、Lasse Karstensen等人撰写。
COPYRIGHT¶
本文档使用与Varnish本身相同的许可。有关详细信息,请参阅许可证。
版权所有(C)2006 Verdens Gang AS
版权所有(C)2006-2015 Varnish软件AS
评论¶
可以使用以下命令注释掉VCL的单行
//
或#
。可以使用以下命令将多行块注释掉/*
block*/
。示例::