架构师日记——Varnish的VCL子程序

一个子程序就是一串可读和可用的代码,子程序在VCL中没有参数,也没有返回值。示例如下:

sub pipe_if_local{
    
    
    if(client.ip ~ local){
        pipe;
    }
}

调用一个子程序,使用子程序的关键字名字,如下所示

call pipe_if_local;

varnish的工作流程

有很多默认子程序和varnish的工作流程相关,这些子程序会检查和操作http头文件和各种各种的请求,决定那个、哪些请求被使用,如果这些子程序没有被定义,或者没有完成预定的处理而被终止,控制权将转交给默认的子程序,他们是:
1.vcl_init
当VCL加载是调用,之后加载客户请求。一般用于初始化VMOD模块
2.vcl_recv
在请求的开始被调用,在接收、解析后,决定是否响应请求,怎么相应,使用哪个后台服务器。在vcl_recv中,可以修改请求,比如可以修改cookies,添加或者删除请求的头信息。注意vcl_recv中只有请求的目标。vcl_recv子程序以下面的关键字结束:error code [resson]、pass、pipe、lookup
3.vcl_pipe
请求进入pipe模式的时候被调用,在这个模式,请求会被passed到后端服务器,在连接关闭前,无论是这个客户端还是对应的后端服务器的数据,都会进入pass模式。vcl_pipe子程序以下面的关键字结束:error code [reason]、pipe
4.vcl_pass
请求进入pass模式的时候被调用,在这个模式,请求会被passed到后端服务器,后端服务器的应答会被passed给客户端,但是不会被缓存。相同客户端的随后的请求正常处理。vcl_pass子程序以下面的关键字结束:error code [reason]、pass、restart
5.vcl_hash
使用req.hash +=req.http.Cookie或者HTTP头文件包含cookie生成hash字符串。vcl_hash将以下的关键字结束:hash
6.vcl_hit
当一个请求从cache中命中需要的内容,vcl_hit子程序以下面的关键字结束:error code [reason]、pass、restart、deliver
7.vcl_miss
当需要的内容没有在缓存中命中的时候被调用,决定是否尝试到后端服务器查找目标,从哪个后端服务器查找目标,vcl_miss子程序以下面的关键字结束:error code [reason]、pass、fetch
8.vcl_fetch
在一个文件成功从后台获取被调用,用场他的任务就是改变response heaeders,出发ESI进程,在请求失败的时候轮询其他服务器。在vcl_fetch中一样的包含请求的对象,还有返回对象beresp,他将会包含后端服务器的返回信息。以下面的关键字结束:error code [reason]、pass、restart、deliver、hit_for_pass
9.vcl_deliver
当一个没有被cached内容交付给客户端的时候被调用,vcl_deliver子程序以下面关键字结束:deliver、restart
10.vcl_error
当hit错误或者发生内部错误的时候。以下面的关键字结束:deliver、restart
11vcl_fini
当销毁VCL程序的时候调用,return的值ok表示征程销毁VCL程序

VCL工作流程图如下

这里写图片描述

中文解析版

这里写图片描述

Actions

VCL中主要有如下动作:
1.pass:当一个请求被pass后,这个请求将通过varnish转发到后端服务器,该请求不会被缓存,后续的请求仍通过Varnish处理。pass可以放在vcl_recv和vcl_fetch中,示例如下

if(req.uri ~ "\.jsp$"){
    return (pass);//如果是.jsp结尾,交由后端服务器处理
}

2.lookup:但疫情请求在vcl_recv中被lookup后,varnish将从缓存中提取数据,如果缓存中没有数据,将被设置为pass,不能在vcl_fetch中设置lookup。

3.pipe:pipe和pass相似,都要访问后端服务器,不过当进入pipe模式后,在此连接未关闭前,后期的所有请求都直接发到后端服务器,不经过Varnish的处理

4.deliver:请求的目标被缓存,然后发送给客户端

5.hit_for_pass:表示直接从后端获取数据,回传件一个hit_for_pass的对象,该对象的TTL值将会被设置成bereso.ttl的当前值。用来控制vcl_deliver如果处理当前的请求,后续的请求会直接vcl_pass,可在vcl_fetch中用,示例如下

if(beresp.ttl <= 0s||beresp.http.Set-Cookie||beresp.http.Vary == "*"){
    set beresp.ttl =120s;//接下来的120s内都会直接走vcl_pass
    return (hit_for_pass);
}

6.fetch:从后端服务器获取请求目标,控制权转交给vcl_fetch。

7.hash:进入Hash模式

8.restart:重启本次事务,重新返回给vcl_recv,如果重启次数超过
max_restarts报错

9.ok:表示正常

10.error:表示错误

猜你喜欢

转载自blog.csdn.net/qq_32198277/article/details/76376857