varnish单台web主机实例+多台web主机实例

软件包提取码:b17b
vcl语言进行集中管理
vcl中的模块:

  • vcl_recv(receive) 用来接收客户端的请求
  • vcl_hash(lookup) 如果请求的是静态数据则进入到varnish本身的缓存中
  • vcl_pass(pass) 当请求为动态数据 则去后端获取 varnish不缓存动态数据
  • vcl_pipe(pipe) 当请求为非正常请求时 则拒绝
  • vcl_hit(hit) 在varnish缓存中找到对应数据(命中)
  • vcl_miss(miss) 在varnish缓存中没有找到对应数据(未命中)
  • vcl_fetch(fetch) 将请求交给后端
  • vcl_deliver(deliver) 讲求请响应给客户端
    预设变量:
  • req 客户端发送给varnish请求使用的变量
  • req.url 客户端对varnish请求的url
  • req.http 客户端对varnish请求的头部信息
  • req.http.host 和互动最varnish域名
  • bereq varnish给后端服务器发送的请求
  • bereq varnish对后端服务器请求的url
  • bereq.http 对后端服务器请求的头部信息
  • resp varnish对客户端的响应
  • resp.http varnish响应的头部信息
  • resp.status 返回状态码
  • beresp 服务器给varnish的响应
  • beresp.uncacheable 响应数据是否不缓存
  • beresp.ttl 响应数据缓存时间
  • obj 缓存在varnish中的数据
  • obj.ttl 缓存在varnish本地缓存的时间
  • obj.hits varnish缓存的命中次数
  • hash_data() 对客户端请求的内容进行hash计算
  • hash_data(req.url)
  • hash_data(rep.url.host)
  • hash_data(server.ip)
    vcl语法:
  •  运算符:
     =赋值运算符
     == 比较运算符
     ~正则匹配
     !非
     != 不等于
     !~ 不匹配
     && || 与非
    
  •  数据类型:
     字符串 “abc”
     布尔值 true false
     时间 s秒 m分钟 d天
    
  • 条件谈判
  •  if else
    

单主机实例

客户端192.168.1.1
varnish192.168.1.2
web192.168.1.3
[root@CentOS2 ~]# vim /usr/local/varnish/default.vcl
 16 probe health {
 17         .url = "/";     #从/开始
 18         .timeout = 3s;   #超时时间
 19         .interval = 1s;   #间隔时间
 20         .window = 5;    #能同时维持5个窗口运行
 21         .threshold = 3;   #至少3个成功
 22 }
 23 backend web {   #后端主机
 24     .host = "192.168.1.3";
 25     .port = "80";
 26     .probe = health;
 27 }
 28 sub vcl_recv {     #用来接收客户端请求的模块
 29     set req.backend_hint = web;   #当请求命中后端web  才接收请求
 30     if(req.http.X-Forwarded-For){#如果在客户端的请求头当中看到这个字段  则就证明经过了代理
 31         set req.http.X-Forwarded-For=req.http.X-Forwarded-For+ "," +client.ip;
 32         }   #则需要重新建立请求头部把这个字段后面加上代理的ip和客户端的ip为了服务端能够获取到client的ip
 33     else{
 34         set req.http.X-Forwarded-For=req.http.X-Forwarded-For;    #如果没有  不改变
 35             }
 36     if(req.method != "GET" &&
 37         req.method != "POST" &&
 38         req.method != "DELETE" &&
 39         req.method != "HEAD" &&
 40         req.method != "PUT"     #如果请求是不正常的请求方式
 41         ){
 42         return(pipe);   #则进入到pipe模块中
 43             }
 44     if(req.url ~ "\.(html|htm|png|jpg$)"){	#如果客户端的请求url中是以.html结尾   则是静态数据
 45         return(hash);    #则进入到hash模块中
 46             }
 47     if(req.url ~ "\.php$"){   #如果请求是以.php结尾   则是动态数据
 48         return(pass);      #则进入到pass模块中
 49             }
 50         return(hash);   #其余全部进入到hash模块中
 51 }
 52 sub vcl_hash{    #静态数据模块
 53     hash_data(req.url);   #对客户端的请求路径进行hash
 54         if(req.http.host){    #如果请求头当中包含域名  
 55             hash_data(req.http.host);  #则hash域名
 56                 }
 57         else{
 58             hash_data(server.ip);   #其余haship
 59                 }
 60 }
 61 sub vcl_pass{    #动态请求数据块
 62     return(fetch);   #直接将请求交给后端
 63 }
 64 sub vcl_pipe{   #不正常请求的模块
 65     return(pipe);   #直接结束
 66 }
 67 sub vcl_miss{      #缓存未命中
 68     return(fetch);   #直接将请求交给后端
 69 }
 70 sub vcl_hit{    #缓存命中
 71     return(deliver);   #直接响应
 72 }
 73 sub vcl_backend_response{    #后端数据模块
 74     if(bereq.url ~ "\.php$"){   #如果varnish对后端请求的是动态数据   则不缓存
 75         set beresp.uncacheable = true;
 76     }
 77     if(bereq.url ~ "\.html$"){    #如果varnish对后端请求的是静态数据
 78         set beresp.ttl = 300s;   #则缓存300s
 79     }
 80 }
 81 sub vcl_deliver{    #结束模块
 82     if(obj.hits > 0){  #如果命中次数大于0
 83         set resp.http.X-cache = "hit~~";
 84     }    #则在varnish对客户端的响应头部建立hit~~~
 85     else{
 86         set resp.http.X-cache = "miss~~";  #其余   则在varnish对客户端的响应头部建立miss~~
 87     }
 88 }
[root@CentOS2 ~]# varnishd -C -f /usr/local/varnish/default.vcl	#检测语法
[root@CentOS2 ~]# varnishd -f /usr/local/varnish/default.vcl	#启动服务

客户端验证:

[root@CentOS1 ~]# curl -I 192.168.1.2
HTTP/1.1 200 OK
Date: Mon, 22 Jun 2020 03:01:07 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Mon, 22 Jun 2020 03:00:36 GMT
ETag: "c-5a8a3726a3545"
Content-Length: 12
Content-Type: text/html; charset=UTF-8
X-Varnish: 2
Age: 0
Via: 1.1 varnish-v4
X-cache: miss~~~	#第一次为miss
Accept-Ranges: bytes
Connection: keep-alive

[root@CentOS1 ~]# curl -I 192.168.1.2
HTTP/1.1 200 OK
Date: Mon, 22 Jun 2020 03:01:07 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Mon, 22 Jun 2020 03:00:36 GMT
ETag: "c-5a8a3726a3545"
Content-Length: 12
Content-Type: text/html; charset=UTF-8
X-Varnish: 5 3
Age: 2
Via: 1.1 varnish-v4
X-cache: hit~~~	#第二此为hit
Accept-Ranges: bytes
Connection: keep-alive

多主机实例

[root@CentOS2 ~]# vim /usr/local/varnish/default.vcl 
probe health {
    .url = "/";
    .timeout = 3s;
    .interval = 1s;
    .window = 5;
    .threshold = 3;
}
backend web1 {
    .host = "192.168.1.3";
    .port = "80";
    .probe = health;
    .max_connections = 100;
}
backend web2 {
    .host = "192.168.1.4";
    .port = "80";
    .probe = health;
    .max_connections = 100;    #最大连接
}
acl allow {   #访问控制列表   allow是名称
    "127.0.0.1";   #本地回环
    "localhost";   #域名主机名
    "192.168.1.2";   #ip
}
import directors;   #导入集群模块
sub vcl_init{   #导入轮询模块
    new back = directors.round_robin();   #使用动态轮询的方式
    back.add_backend(web1);   #使用上面的主机
    back.add_backend(web2);
}   
sub vcl_recv{
   set req.backend_hint = back.backend();   #自动屏蔽掉后端不正常的主机
        if(req.method == "PURGE"){     #当请求方式为purge
            if(client.ip !~ allow){    #如果请求的ip不匹配allow列表
                return(synth(405,"not allowed"));    #将返回状态码405
            }
            else{
                return(purge);   #其余则进入到清除缓存的模块
            }
        }
       if(req.http.host ~ "^qqq"){     #如果客户端的请求域名是以qqq开头
            set req.backend_hint = web1;    #则将请求交给web1
        }
        if(req.http.host ~ "^www"){    #如果客户端的请求域名是以www开头
            set req.backend_hint = web2;     #则将请求交给web2
        }
        if(req.url ~ "\.(php|asp|aspx|jsp|do)($|\?)"){   #如果请求的是动态数据
            return(pass);     #则把请求交给pass模块
        }
        if(req.url ~ "\.(css|html|htm|jpeg|png|mp4)$"){    #如果请求是静态数据
            return(hash);      #则把请求交给hash模块
        }
         if(req.method != "GET" &&
           req.method != "POST" &&
           req.method != "DELETE" &&
           req.method != "PUT" &&
           req.method != "HEAD"
          ){      
            return(pipe);      #如果请求方式不是正常的请求方式   #则拒绝连接
         }                                                         
        if(req.method != "GET" && req.method != "HEAD"){   #当请求方式不是get或者head是
            return(pass);     #则进入到动态数据模块     因为其余的请求方式和数据库都是有联系的
        }
       if(req.http.Authorzation){   #如果请求是认证
            return(pass);           #则进入到pass模块中
        }
        if(req.http.Accept-Encoding){    #如果在客户端的请求头中有这个字段
            if(req.url ~ "\.(png|gif|bz2|zip)$"){    #客户端如果请求的是压缩文件
                unset req.http.Accept-Encoding;     #则不用建立这个请求头   防止web再次压缩
            }
                elseif(req.http.Accept-Encoding ~ "gzip"){     #如果请求头中匹配到gzip
                    set req.http.Accept-Encoding = "gzip";    #则建立这个请求头
                }
                elseif(req.http.Accept-Encoding ~ "deflate"){
                    set req.http.Accept-Encoding = "deflate";
                }
            else{
                unset req.http.Accept-Encoding;    #其余则不用建立
            }
        }
}
sub vcl_pipe{    #拒绝连接模块   直接结束
    return(pipe);
}
sub vcl_pass{    #动态数据模块   进入到后端
    return(fetch);
}
sub vcl_hash{      #静态数据模块
    hash_data(req.url);      #hash请求的路径
        if(req.http.host){     
            hash_data(req.http.host);    #hash域名
        }
        else{
            hash_data(server.ip);   #其余hash   ip 
            if(req.http.Accept-Encoding ~ "deflate"){    #当请请求头部有这个字段  则hash   deflate
                hash_data("deflate");
            }
            if(req.http.Accept-Encoding ~ "gzip"){    #如果客户端请求头部中包含编码类型 web是以压缩文件进行传输的 是由客户端
                hash_data("gzip");                   本身来进行解压    那么为了varnish能够把压缩有的文件进行缓存   所以填写了这个
            }                                                        Accept-Encoding字段
        }
}
sub vcl_backend_response{     #后端能够找到对应的数据
    if(bereq.url ~ "\.(php|asp|do)($|\?)"){    #当时动态数据时
        set beresp.uncacheable = true;   #不缓存   直接响应给客户端
        return(deliver);
    }
    if(bereq.url ~ "\.(css|html|htm|png)$"){     #静态数据  
        set beresp.ttl = 15m;             #缓存15分钟时间
    } 
    if(bereq.url ~ "\.(gz|bz2|zip|mp3)$"){    #压缩文件
        set beresp.ttl = 300s;                #缓存300s
    }
    return(deliver);
}
sub vcl_backend_error{     #后端找不到对应的数据
    if(beresp.status == 503){    #当状态码为503
        set beresp.status = 200;    #把状态码换成200
        synthetic("hahahaha");    #返回页面 hahahaha
        return(deliver);
    }
}
sub vcl_purge{   #清除缓存模块
    return(synth(200,"success~~~~"));   #状态码变成200  成功
}
sub vcl_deliver{    #结束模块
    if(obj.hits > 0){   #如果命中次数大于0
         set resp.http.X-cache = "hit~~~~~";    #则在varnish对客户端的响应头部建立hit~~
    }
   else{
         set resp.http.X-cache = "miss~~~~";   #其余   则在varnish对客户端的响应头部建立miss~~
     }
 }
root@localhost ~]# killall -9 varnishd
[root@CentOS2 ~]# varnishd -f /usr/local/varnish/default.vcl 

验证

客户端访问
[root@CentOS ~]# curl -I 192.168.1.2
X-cache: miss~~~~
[root@CentOS ~]# curl -I 192.168.1.2
X-cache: hit~~~~
客户端清除缓存
[root@CentOS ~]# curl -I http://192.168.1.2 -X PURGE
HTTP/1.1 405 not allowed
varnish清除
[root@CentOS ~]# curl -I http://192.168.1.2 -X PURGE
HTTP/1.1 200 success~~~~

错误页面是否能访问成功
把varnish的缓存清除
后端的web关掉
客户端访问的
[root@CentOS ~]# curl -I 192.168.1.2
HTTP/1.1 200 OK
[root@CentOS ~]# curl  192.168.1.2
hahahaha

访问qqq  www出两个页面
后端服务开启
反向代理清除缓存   varnish重启
客户端:
[root@CentOS ~]# vim /etc/hosts
192.168.1.2 www.abc.com   反向代理的ip
192.168.1.2 qqq.abc.com
[root@CentOS ~]# curl www.abc.com
1111
[root@CentOS ~]# curl qqq.abc.com
2222
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值