27.3 VCL 语法基础
VCL 语法基础
varnish 的缓存配置,使用的是 VCL,一种与 C 类似的域专有类型的配置语言。本节我们先来对 VCL 做一个介绍。
1. VCL 组成与处理流程
1.1 VCL 组成
|
|
VCL 可以看作是在 C 语言基础上二次开发的子语言,保留了 C 语言基本的语法,并额外附加了特性:
- 首先作为一门语言 VCL 具有变量,赋值,条件判断等基本语法特性,需要额外提醒的是 VCL 没有循环
- 为了在更高层级上抽象缓存处理逻辑, VCL 在 C 基础上添加了"状态引擎"(state engine)
- VCL有多个状态引擎,状态之间存在相关性,但状态引擎彼此间互相隔离;每个状态引擎可使用
return(x)
指明关联至哪个下一级引擎;每个状态引擎对应于vcl文件中的一个配置段,即为subroutine
1.2 VCL 状态引擎
VCL 的状态引擎可以分为三类:
Client Side
:
- 作用: 客户端请求的状态引擎
- 包括:
vcl_recv, vcl_pass, vcl_hit, vcl_miss, vcl_pipe, vcl_purge, vcl_synth, vcl_deliver...
Backend Side
:
- 作用: 后端服务器响应相关的状态引擎
- 包括:
vcl_backend_fetch, vcl_backend_response, vcl_backend_error
- 两个特殊的引擎:
vcl_init
: 在处理任何请求之前要执行的vcl代码:主要用于初始化VMODs;vcl_fini
: 所有的请求都已经结束,在vcl配置被丢弃时调用;主要用于清理VMODs;
1.2 VCL 处理流程
varnish 已经为状态引擎内置了关联逻辑,这种内在逻辑就是缓存的处理流程。varnish 不同版本缓存处理的流程并不相同,下面是 varnish4.0 流程图。
2. VCL 语法
2.1 VCL 基础特性
VCL的语法格式:
vcl 4.0;
: 必需位于开头,表示 VCL 的版本//, #, /* foo */
: 注释;sub sub_name {}
: 使用 sub 关键字定义状态域,例如sub vcl_recv { ...}
return(sub_name)
: 用于实现状态引擎转换;- 没有循环, 并且受限于引擎的内建变量
VCL 有限状态机
- 每一个请求都会被单独的线程处理,并且在任何时间都与其他请求无关
return(action);
将请求从当前状态引擎传递到一个新的状态引擎- 状态引擎存在逻辑上的关联,但是彼此是相互独立的
- 内置的 VCL 代码总是被附加自定义的 VCL 代码之后
2.2 三类主要语法
|
|
2.3 变量
内建变量:
req.*
:
- 作用: request,表示与客户端发来的请求报文相关的变量
req.http.*
- 作用: http 首部字段相关变量
- eg: `req.http.User-Agent, req.http.Referer, …``
bereq.*
:
- 作用: 由varnish发往后端主机的httpd请求相关;
bereq.http.*
beresp.*
: 由BE主机响应给varnish的响应报文相关;beresp.http.*
resp.*
: 由varnish响应给client相关;obj.*
: 存储在缓存空间中的缓存对象的属性;只读;
|
|
|变量组|变量|作用| |:—|:—|| |bereq.|bereq.http.HEADERS|| ||bereq.request|请求方法;| ||bereq.url|请求的url;| ||bereq.proto|请求的协议版本;| ||bereq.backend|指明要调用的后端主机;| |req.|req.http.Cookie|客户端的请求报文中Cookie首部的值| ||req.http.User-Agent |~ 表示使用正则表达式| |beresp.|beresp.http.HEADERS|| ||beresp.status|响应的状态码| ||beresp.backend.name|BE主机的主机名;| ||beresp.ttl|BE主机响应的内容的余下的可缓存时长| |resp.|reresp.proto|协议版本| |obj.|obj.hits|此对象从缓存中命中的次数| |obj.|obj.ttl|对象的ttl值| |server.|server.ip|| ||server.hostname|| |client.|client.ip||
用户自定义变量
使用 set, unset
自定义变量和取消变量
2.3 内置操作
内置函数
常用内置函数:
regsub(str, regex, sub)
: 把str中被regex第一次匹配到字符串替换为sub;主要用于URL Rewriteregsuball(str, regex, sub)
: 把str中被regex每一次匹配到字符串均替换为sub;ban(boolean expression)
: Bans所有的其URL可以被此处的regex匹配到的缓存对象;hash_data(input)
: 指明哈希计算的数据;减少差异,以提升命中率;synth(status,"STRING")
:purge操作;
关键字
常见的内置关键子:
- call
- subroutine
- return(action)
- new
- set
- unset
操作符:
- 判断:
==, !=, ~, >, >=, <, <=
- 逻辑操作符:
&&, ||, !
- 变量赋值:
=
正则表达式
VCL 使用 ~
表示使用正则表达式。eg: req.url ~ "(?i)^/(login|admin)"
, 其中 (?i)
表示不区分字符大小写。
2.4 示例
|
|