VCL语法非常灵活,功能强大。下面是一个Varnish对应多台Web主机的应用实例,具有负载分担和健康检测机制。配置完成的vcl.conf文件如下:
#下面定义了4台后端Web服务器
backend webserver1 {
.host = "192.168.12.12";
.port = "80";
}
backend webserver2 {
.host = "192.168.12.13";
.port = "80";
}
backend webserver3 {
.host = "192.168.12.14";
.port = "80";
}
backend webserver4 {
.host = "192.168.12.15";
.port = "80";
}
#定义一个名为webserver的director,也就是由webserver1和webserver2两台后端服务器随机分担
#请求。“.weight”用来指定两台后端服务器的权值。权值高的处理请求的几率就高些
director webserver random {
{.backend = webserver1; .weight = 5; }
{.backend = webserver2; .weight = 8; }
}
#这里设定清理缓存的规则,Varnish允许localhost、127.0.0.1和192.168.12.***三个来源IP通过
# PURGE方法清除缓存
acl purge {
"localhost";
"127.0.0.1";
"192.168.12.0"/26;
}
sub vcl_recv {
#这里设定,当发送PURGE请求的客户端不是在acl中设定的地址时,将返回405状态代码,提示
#“Not allowed”。当请求的URL是以.php和.cgi结尾时,则交给后端服务器去处理
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
elseif(req.url ~ "\.(php|cgi)($|\?)") {
return (pass);
}
else {
return (lookup);
}
}
#下面设定域名访问策略,其实也是设定对后端主机健康状态检测的一个机制。如果访问www.ixdba.net
#或者bbs.ixdba.net,并且请求重启次数为0,则将请求交给webserver来处理。如果请求重启次数
#为1,则将请求交给webserver3处理。如果访问img.ixdba.net或者images.ixdba.net,则将
#请求交给webserver4来处理
if((req.http.host ~"^(www.|bbs.)?ixdba.net")&&(req.restarts == 0)) {
set req.backend = webserver;
} elseif(req.restarts == 1) {
set req.backend = webserver3;
}
if(req.http.host ~"^(img.|images.)?ixdba.net") {
set req.backend = webserver4;
}
#下面定义缓存的策略。当请求以.cgi和.php结尾及带有?的URL时,不进行缓存,直接从后端服务器
#读取内容。其他请求都进入lookup模式,也就是进入cache中通过hash表寻找被请求的数据
if (req.request != "GET" && req.request != "HEAD")
{
return (pipe);
}
elseif (req.url ~ "\.(cgi|php)($|\?)")
{
return (pass);
}
elseif (req.http.Authenticate || req.http.Authorization) {
return (pass);
}
return (lookup);
}
#如果请求的类型是PURGE方法,Varnishd会将此请求的缓存周期设置为0,也就是使这个URL的缓存失效,
#从而达到刷新Varnish缓存的目的
sub vcl_hit
{
if (req.request == "PURGE") {
set obj.ttl = 0s;
error 200 "Purged.";
}
if (!obj.cacheable)
{
return (pass);
}
if (obj.http.Vary)
{
unset obj.http.Vary;
}
}
sub vcl_miss
{
if (req.request == "PURGE") {
error 404 "Not in cache.";
}
}
#定义hash的值,并且处理压缩内容
sub vcl_hash {
set req.hash += req.url;
if (req.http.host) {
set req.hash += req.http.host;
} else {
set req.hash += server.ip;
}
if ( req.http.Accept-Encoding ){
if (req.url ~ "\.(jpg|jpeg|png|gif|rar|zip|gz|tgz|bz2|tbz|mp3|ogg|swf|exe|flv|avi|rmvb|rm|mpg|mpeg|pdf)$") {
} else {
set req.hash += req.http.Accept-Encoding;
}
}
return (hash);
}
sub vcl_fetch
{
if (!beresp.cacheable) {
return (pass);
}
if (beresp.http.Set-Cookie) {
return (pass);
}
#定义在什么状态下进入restart模式
if (beresp.status == 500 || beresp.status == 501 || beresp.status == 502 || beresp.status == 503 || beresp.status == 504 || beresp.status == 404)
{
return (restart);
}
#下面定义不缓存含有哪些HTTP头的请求
if (beresp.http.Pragma ~ "no-cache" || beresp.http.Cache-Control ~ "no-cache" || beresp.http.Cache-Control ~ "private") {
return (pass);
}
#定义不同内容的缓存时间
if (req.request == "GET" && req.url ~ "\.(css|js|html|htm)$") {
set beresp.ttl = 300s;
}
if (req.request == "GET" && req.url ~ "\.(gif|jpg|jpeg|bmp|png|tiff|tif|ico|img|bmp|wmf)$") {
.........................................................