内置子程序
varnish的各种内置子程序会在客户端和后端处理请求的过程中调用。
通过varnish处理状态可以查看各种状态的图示,并可了解它们是如何和核心代码进行关联。
client端
vcl_recv
在一个请求开始时会被调用,在完整的请求接收并解析之后,在重启或者包含有ESI的结果之后。
它的目的是决定是否服务这个请求、可能会修改它,并决定怎样服务并决定使用哪台后端服务器来提供服务等等。
vcl_recv子程序可以通过调用return来结束,参数可以是下列关键词:
hash继续处理对象以备缓存。将请求转到vcl_hashpass进入pass模式,处理转到vcl_pass。pipe进入pipe模式,处理转到vcl_pipesynth(status code, reason)带着synth的参数resp.status和resp.reason转到vcl_synth处理。purge清楚对象。控制权将会通过vcl_hash转到vcl_purge。
vcl_pipe
进入pipe模式时调用,在这种模式下,请求将会被传递到后端,后续的数据不管是从客户端还是后端来的都会以不变的方式传送,直到连接关闭为止。也就是说,varnish只会做简单的TCP代理,来回的传输数据。在这种模式下的连接,在vcl_pipe之后不会有任何的vcl子程序会被调用。
vcl_pipe子程序可以通过调用return()来结束,通过以下关键字:
pipe使用pipe模式进行处理synth(status code, reason)带着synth的参数resp.status和resp.reason转到vcl_synth处理。
vcl_pass
进入pass模式时调用。在这种模式下,请求会直接传递到后端主机,但是后端主机的响应会直接返回给客户端,而不会进行缓存。同一客户端的大量请求会按照规则处理。
vcl_pass子程序可以通过调用return()来结束,通过以下关键字:
fetch继续使用pass模式,发起后端请求restart重新启动事务。增加了重新启动计数器。如果重启的次数超过了max_restarts的设置,就会抛出一个错误。synth(status code, reason)带着synth的参数resp.status和resp.reason转到vcl_synth处理。
vcl_hit
当在缓存中成功查到的时候调用。读到的数据可能是已经过期的:如果有宽限时间或者保留时间的话,它可以是一个0或者负的ttl。
vcl_hit子程序可以通过调用return()来结束,通过以下关键字:
deliver传递对象。如果它已经过期了,那么将会触发重新从后端获取数据动作。miss同步刷新缓存的对象,尽管缓存已经命中。并将会转给vcl_miss进行处理。pass切换到pass模式。控制将会转到vcl_pass进行处理。restart重新启动事务。增加了重新启动计数器。如果重启的次数超过了max_restarts的设置,就会抛出一个错误。synth(status code, reason)带着synth的参数resp.status和resp.reason转到vcl_synth处理。fetch(已废弃) 和miss是一样的。将会在将来的版本中去除。
vcl_miss
当在缓存找不到请求内容或者使用vcl_hit返回fetch时调用该方法。
该函数主要用于判断是否要从后端服务器来获取数据,从哪一个后端获取内容。
vcl_miss子程序可以通过调用return()来结束,通过以下关键字:
fetch从后端获取请求对象,并转给vcl_backend_fetch进行处理。pass切换到pass模式,并转给vcl_pass进行处理。restart重新启动事务。增加了重新启动计数器。如果重启的次数超过了max_restarts的设置,就会抛出一个错误。synth(status code, reason)带着synth的参数resp.status和resp.reason转到vcl_synth处理。
vcl_hash
在vcl_recv为请求创建哈希值之后被调用,这将会使用一个key去在varnish中查找这个对象。
vcl_hash子程序可以通过调用return(lookup)来结束:
lookup从缓存中查找对象。当是来了一个purge的话会将控制传递到vcl_purge然后返回给vcl_recv。否则控制权传递至vcl_miss,vcl_hit或者vcl_pass。
vcl_purge
pruge操作执行后调用此函数,所有他的变种将被回避。
vcl_purge子程序可以通过调用return()来结束,通过以下关键字:
restart重新启动事务。增加了重新启动计数器。如果重启的次数超过了max_restarts的设置,就会抛出一个错误。synth(status code, reason)带着synth的参数resp.status和resp.reason转到vcl_synth处理。
vcl_deliver
将在缓存中找到请求的内容发送给客户端前调用此方法,当然vcl_synth除外。
vcl_deliver子程序可以通过调用return()来结束,通过以下关键字:
deliver将对象传递给客户端。restart重新启动事务。增加了重新启动计数器。如果重启的次数超过了max_restarts的设置,就会抛出一个错误。synth(status code, reason)带着synth的参数resp.status和resp.reason转到vcl_synth处理。
vcl_synth
主要被用于返回组合对象。这个组合对象会在VCL里面进行合成,而不是直接从后端拉取。它的内容可以使用synthetic()函数来进行构造。
vcl_synth定义的对象不会存入缓存,相反vcl_backend_error定义的对象倒是可以被存入缓存。
这个子程序可以通过调用return()来结束,通过以下关键字:
deliver直接把vcl_synth定义的对象返回给客户端,而不调用vcl_deliver。synth(status code, reason)带着synth的参数resp.status和resp.reason转到vcl_synth处理。
后端
vcl_backend_fetch
在向后端主机发送请求前,调用此函数,可修改发往后端的请求。
vcl_backend_fetch子程序可以通过调用return()来结束,通过以下关键字:
fetch从后端拉取数据abandon放弃后端请求,除非是后端拉取命令。请求会带着预设为503的resp.status参数,并转到vcl_synth进行处理。
vcl_backend_response
当从后端服务器成功取到响应头之后调用。
对于304响应,varnish核心代码会在调用vcl_backend_response之前修改beresp:
- 如果gzip的状态发生改变,
Content-Encoding没有被设置。 - 在304响应中不存在从现有对象中复制的响应头。如果在缓存中存在,那么
Content-Length会被复制,否则就丢弃。 - 状态设置为200.
beresp.was_304标识标识这个条件的响应处理已经发生。
注意: 后端请求时独立的客户端条件请求,所以客户端可能受到304响应,不管后端是否是有条件的。
vcl_backend_response子程序可以通过调用return()来结束,通过以下关键字:
deliver对于304响应,会创建一个最新的缓存对象。否则会从后端拉取对象内容,并将结果返回给所有在等待的客户端请求,可能是并行(流)。abandon放弃后端请求。除非后端请求是背景取指令,在客户端会带着被设置为503的resp.status参数传递给vcl_synth处理。retry重试后端事物。增加重试计数器,如果重试次数大于 max_retries 设置的值,将会转给vcl_backend_error进行处理。
vcl_backend_error
如果为我们从后端服务拉取数据失败或者重试次数超出的时候被调用。
在VCL中合成的组合对象,其内容可能使用synthetic()函数进行合成。
vcl_backend_error子程序可以通过调用return()来结束,通过以下关键字:
deliver传递错误页面retry重试后端事物。增加重试计数器,如果重试次数大于 max_retries 设置的值,在客户端上面的vcl_synth将会返回resp.status=503。
vcl.load / vcl.discard
vcl_init
在任何请求通过它之前,当VCL被加载时被调用。通常用来初始化VMODs。
vcl_init子程序可以通过调用return()来结束,通过以下关键字:
ok正常返回,继续加载VCLfail中止加载VCL
vcl_fini
只有在所有请求都从VCL退出之后,当VCL被丢弃之后调用。经常被用来清理VMODs。
vcl_fini子程序可以通过调用return()来结束,通过以下关键字:
ok正常返回,丢弃VCL