varnish

varnish:
vcl语言进行管理

模块:
在这里插入图片描述
vcl_recv:用来接收客户端的请求
vcl_hash:如果请求是静态数据 则进入到varnish本身的缓存中
vcl_pass:当请求为动态数据 则去后端获取
注:varnish不缓存动态数据
vcl_pipe:当请求为非正常请求时,则直接拒绝
vcl_hit:在varnish缓存中找到对应的数据(命中)
vcl_miss:在varnish缓存中没有找到对应的数据(未命中)
vcl_fetch:将请求交给后端
vcl_deliver:将请求响应给客户端

因为要是使用判断的条件。所以会使用到一些固定的预设变量

预设变量:
req:客户端发送给varnish请求使用的变量(rep request请求)
req.url:客户端对varnish请求的url(路径)
req.http:客户端对varnish的请求头部信息
bereq:varnish给后端服务器发送的请求(bereq:backend request)
bereq.url:varnish对后端服务器的请求的url
bereq.http:varnish对后端服务器的请求的头部信息
resp:varnish对客户端的响应(resp:response响应)
resp.http:varnish响应客户端的头部信息
resp.status:返回状态码
beresp:服务器节点给varnish的响应(beresp:backend response)
beresp.uncacheable:响应数据是否不缓存
beresp.ttl:响应数据的缓存时间
obj:缓存在varnish中的数据
obj.ttl:varnish本地缓存的时间
obj.hits:varnish缓存的命中次数
hash_data():对客户端请求的内容进行hash计算
hash_data(req.url) 计算请求的路径
hash_data(req.url.host) 计算请求的域名
hash_data(server.ip) 计算请求的ip

vcl语法
运算符:
= 赋值运算符
== 比较运算符
~ 正则匹配
! 非
!= 不等于
!~ 不匹配
&& | | 与非

数据类型:
字符串 “abc”
布尔值 true false
时间 s秒 m分钟 d天

条件判断:
if else

单主机实例:
环境:

client192.168.10.2
varnish192.168.10.3
web192.168.10.10

操作:

web:
安装httpd服务并修改页面内容

varnish:

[root@localhost varnish-4.1.11]# vim /usr/local/varnish/default.vcl 
13 vcl 4.0;
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.10.10";
 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对后端请求的是静态数据  则缓存300s
 78        set beresp.ttl = 300s;
 79     }
 80 }
 81 sub vcl_deliver{  #结束模块
 82     if(obj.hits > 0){  #如果命中次数大于0
 83        set resp.http.X-cache = "hit~~~~~";  #则在varnish对客户端的响应头部建立hit~~
 84     }
 85     else{
 86         set resp.http.X-cahe = "miss~~~~~";  #其余  则在varnish对客户端的响应头部建立miss~~
 87     }
 88 }
 [root@localhost varnish-4.1.11]# varnishd -C -f /usr/local/varnish/default.vcl
 #启动
 [root@localhost varnish-4.1.11]# varnishd -f /usr/local/varnish/default.vcl  #执行这条命令时如果它提示端口被占用则可通过killall -9 加占用端口的服务名  进行杀死即可
[root@localhost varnish-4.1.11]# netstat -anput | grep varnishd
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      73810/varnishd      
tcp        0      0 127.0.0.1:44729         0.0.0.0:*               LISTEN      73810/varnishd      
tcp6       0      0 :::80                   :::*                    LISTEN      73810/varnishd      
tcp6       0      0 ::1:42815               :::*                    LISTEN      73810/varnishd

客户端验证:

[root@localhost ~]# curl -I 192.168.10.3
HTTP/1.1 200 OK
Date: Mon, 22 Jun 2020 03:07:31 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Mon, 22 Jun 2020 00:37:46 GMT
ETag: "7-5a8a17399266f"
Content-Length: 7
Content-Type: text/html; charset=UTF-8
X-Varnish: 2
Age: 0
Via: 1.1 varnish-v4
X-cache: miss~~~~~
Accept-Ranges: bytes
Connection: keep-alive

[root@localhost ~]# curl -I 192.168.10.3
HTTP/1.1 200 OK
Date: Mon, 22 Jun 2020 03:07:31 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Mon, 22 Jun 2020 00:37:46 GMT
ETag: "7-5a8a17399266f"
Content-Length: 7
Content-Type: text/html; charset=UTF-8
X-Varnish: 5 3
Age: 14
Via: 1.1 varnish-v4
X-cache: hit~~~~~
Accept-Ranges: bytes
Connection: keep-alive

多主机实例

环境:

client192.168.10.2
varnish192.168.10.3
web1192.168.10.10 httpd 111111
web2192.168.10.20 httpd 22222

注:实验环境直接关闭防火墙即可

操作:

web:
分别安装httpd服务并修改页面内容

varnish:

[root@localhost ~]# vim /usr/local/varnish/default.vcl
16 probe health {
 17     .url = "/";
 18     .timeout = 3s;
 19     .interval = 1s;
 20     .window = 5;
 21     .threshold = 3;
 22 }
 23 backend web1 {
 24     .host = "192.168.10.10";
 25     .port = "80";
 26     .probe = health;
 27     .max_connections = 100;  #最大连接数
 28 }
 29 
 30 backend web2 {
 31     .host = "192.168.10.20";
 32     .port = "80";
 33     .probe = health;
 34     .max_connections = 100;
 35 }
 36 acl allow {   #访问控制列表  allow是名称
 37     "127.0.0.1";   #本地回环
 38     "localhost";  #域名主机
 39     "192.168.10.3"; #ip
 40 }
 41 import directors;  #导入集群模块
 42 sub vcl_init{  #导入轮询模块
 43     new back = directors.round_robin();  #使用动态轮询的方式
 44     back.add_backend(web1);  #使用上面的主机
 45     back.add_backend(web2);
 46 }
 47 sub vcl_recv {
 48    set req.backend_hint = back.backend();  #自动屏蔽掉后端不正常的主机
 49        if(req.method == "PURGE"){  #当请求方式为purge
 50             if(client.ip !~ allow){  #如果请求的ip不匹配allow列表
 51                 return(synth(405,"not allowed")); #将返回状态码405
 52             }
 53             else{
 54               return(purge);  #其余则进入到清除缓存的模块
 55             }
 56        }
 57        if(req.http.host ~ "^qqq"){  #如果客户端的请求域名是以qqq开头
 58           set req.backend_hint = web1;  #则将请求交给web1
 59        }
 60        if(req.http.host ~ "^www"){  #如果客户端的请求域名是以www开头
 61          set req.backend_hint = web2; #则将请求交给web2
 62        }
 63        if(req.url ~ "\.(php|asp|aspx|jsp|do)($|\?)"){  #如果请求的是动态数据
 64           return(pass);  #则把请求交给pass模块
 65        }
 66        if(req.url ~"\.(css|html|htm|jpeg|png|mp4)$"){  #如果请求是静态数据
 67           return(hash);  #则把请求交给hash模块
 68        }
 69        if(req.method != "GET" &&
 70           req.method != "POST" &&
 71           req.method != "DELETE" &&
 72           req.method != "PUT" &&
 73           req.method != "HEAD"
 74          ){
 75            return(pipe);  #如果请求方式不是正常的请求方式  则拒接连接
 76           }
 77         if(req.method != "GET" && req.method != "HEAD"){  #当请求方式不是get或者head时
 78             return(pass);  #则进入到动态数据模块  因为其余的请求方式和数据库都是有联系的
 79         }
 80         if(req.http.Authorzation){  如果请求是认证
 81            return(pass);  #则进入到pass模块中
 82         }
 83         if(req.http.Accept-Encoding){  #如果在客户端的请求头中有这个字段
 84             if(req.url ~ "\.(png|gif|bz2|zip)$"){  #客户端如果请求的是压缩文件
 85                 unset req.http.Accept-Encoding; #则不用建立这个请求头  防止web再次压缩
 86             }
 87                elseif(req.http.Accept-Encoding ~ "gzip"){   #如果请求头中匹配到gzip
 88                   set req.http.Accept-Encoding = "gzip";  #则建立这个请求头
 89                }
 90                elseif(req.http.Accept-Encoding ~ "deflate"){
 91                   set req.http.Accept-Encoding = "deflate";
 92                }
 93             else{
 94              unset req.http.Accept-Encoding;  #其余则不用建立
 95             }
 96         }
 97 }
 98 sub vcl_pipe{  #拒绝连接模块   直接结束
 99       return(pipe);
100 }
101 sub vcl_pass{  #动态数据模块  进入到后端
102       return(fetch);
103 }
104 sub vcl_hash{   #静态数据模块
105     hash_data(req.url);   #hash请求的路径
106       if(req.http.host){
107          hash_data(req.http.host); #hash域名
108       }
109       else{
110         hash_data(server.ip);  #其余hash  ip
111         if(req.http.Accept-Encoding ~ "deflate"){  #当请求头部中有这个字段 则hash   deflate
112              hash_data("deflate");
113         }
114       }
115         if(req.http.Accept-Encoding ~ "gzip"){   #如果客户端请求头部中包含编码类型  web是以压缩文件进行传输的  是由客户端本身来进行解压 那么为了varnish能够把压缩的文件进行缓存 所以填写了这个模块
116            hash_data("gzip");
117         }                          #注  accept-Encoding字段
118 }        
119                                       
120 sub vcl_backend_response{   #后端能够找到对应的数据
121     if(bereq.url ~ "\.(php|asp|do)($|\?)"){   #当是动态数据时
122        set beresp.uncacheable = true;   #不缓存  直接响应给客户端
123        return(deliver);
124     }
125     if(bereq.url ~ "\.(css|html|htm|png)$"){    #静态数据
126          set beresp.ttl = 15m;    #缓存15分钟时间
127     }
128     if(bereq.url ~ "\.(gz|bz2|zip|mp3)$"){   #压缩文件
129         set beresp.ttl = 300s;     #缓存300s
130     }
131     return(deliver);
132 }
133 sub vcl_backend_error{   #后端找不到对应的数据
134     if(beresp.status == 503){   #当状态码为503
135       set beresp.status = 200;  #把状态码换成200
136       synthetic("hahahaha"); #返回页面  hahahaha
137       return(deliver);
138     }
139 }
140 sub vcl_purge{   #清除缓存模块
141     return(synth(200,"success~~~~"));  #状态码变成200  成功
142 }
143 sub vcl_deliver{   #结束模块
144     if(obj.hits > 0){   #如果命中次数大于0
145        set resp.http.X-cache = "hit~~~~~";   #则在varnish对客户端的响应头部建立hit~~
146     }
147     else{
148       set resp.http.X-cache = "miss~~~~";   #其余则在varnish对客户端的响应头部建立miss~~
149     }
150 }
[root@localhost ~]# killall -9 varnishd
[root@localhost ~]# varnishd -f /usr/local/varnish/default.vcl

客户端访问:

[root@localhost ~]# curl -I 192.168.10.3
X-cache: miss~~~~
[root@localhost ~]# curl -I 192.168.10.3
X-cache: hit~~~~~

客户端清除缓存:

[root@localhost ~]# curl -I http://192.168.10.3 -X PURGE
HTTP/1.1 405 not allowed
Date: Tue, 23 Jun 2020 04:24:26 GMT
Server: Varnish
X-Varnish: 5
Content-Type: text/html; charset=utf-8
Retry-After: 5
Content-Length: 251
Connection: keep-alive

varnish清除:

[root@localhost ~]# curl -I http://192.168.10.3 -X PURGE
HTTP/1.1 200 success~~~~
Date: Tue, 23 Jun 2020 04:27:22 GMT
Server: Varnish
X-Varnish: 32772
Content-Type: text/html; charset=utf-8
Retry-After: 5
Content-Length: 255
Accept-Ranges: bytes
Connection: keep-alive

错误页面是否能访问成功 把varnish的缓存清除 后端的web关掉
客户端访问的

[root@localhost ~]# curl -I 192.168.10.3
HTTP/1.1 200 OK
Date: Tue, 23 Jun 2020 04:28:39 GMT
Server: Varnish
X-Varnish: 7
Age: 0
Via: 1.1 varnish-v4
X-cache: miss~~~~
Accept-Ranges: bytes
Connection: keep-alive

[root@localhost ~]# curl  192.168.10.3
hahahaha[root@localhost ~]#

访问qqq www这两个页面
后端服务开启
反向代理清除缓存 varnish重启
客户端:

[root@localhost ~]# vim /etc/hosts
192.168.10.3 www.abc.com
192.168.10.3 qqq.abc.com
[root@localhost ~]# curl www.abc.com
22222
[root@localhost ~]# curl qqq.abc.com
11111

varnish启动参数:
-a:指定varnish服务的监听端口与ip
例 -a 192.168.1.100:80
-f:指定配置文件
例 -f /usr/local/varnish/default.vcl
-n:指定varnish工作目录
例 -n /usr/local/varnish
-P:指定varnish进程PID号存放的文件
例 -P /usr/local/varnish/varnish.pid
-s:指定varnish缓存数据的文件
例 -s /usr/local/varnish/cache.data,1G
-T:管理varnish主机的IP与端口
例 -T 192.168.8.12:3500
-S:管理varnish主机使用的密钥文件
例 -S /etc/vc
-p:指定varnish运行时的参数
例 -p thread_pools=2:指定varnish开启的线程池的个数,与CPU个数或核心数一致
-p thread_pool_min=50:指定每个线程池中最少开启线程数量
-p thread_pool_max=5000:指定每个线程池中最多开启线程数量
-p thread_pool_timeout=30:当线程池中线程的数量超过最小值,且30s内没有客户端的请求,则对线程数量进行释放的最小值
-p lru_interval=30:没有指定缓时间的数据如果一直处于未命中状态,则缓存时间为该值,单位是s
程序–进程(获取程序所需的资源)–线程

[root@localhost ~]# varnish
varnishadm   varnishhist  varnishncsa  varnishtest  
varnishd     varnishlog   varnishstat  varnishtop   
varnishadm管理varnish
使用随机数生成密钥:
[root@localhost ~]# dd if=/dev/random of=/etc/vc count=1
0+1 records in
0+1 records out
115 bytes (115 B) copied, 0.000196612 s, 585 kB/s
[root@localhost ~]# cat /etc/vc
#重启varnish
[root@localhost ~]# killall -9 varnishd
[root@localhost ~]# varnishd -a 192.168.2.10:80 -f /usr/local/varnish/default.vcl -n /usr/local/varnish/ -P /usr/local/varnish/varnish.pid -s file,/usr/local/varnish/cache.data,1G -T 192.168.2.10:3500 -S /etc/vc -p thread_pools=2 -p thread_pool_min=50 -p thread_pool_max=1000 -p thread_pool_timeout=30 -p lru_interval=30
[root@localhost ~]# netstat -anput | grep varnishd
tcp        0      0 192.168.2.10:3500       0.0.0.0:*               LISTEN      19517/varnishd      
tcp        0      0 192.168.2.10:80         0.0.0.0:*               LISTEN      19517/varnishd      
交互式界面:
[root@localhost ~]# varnishadm -T 192.168.2.10:3500 -S /etc/vc
varnish> status
200        
Child in state running
varnish> start
300        
Child in state running
stop
200        
varnish> start
200        
varnish> backend.list
200        
Backend name                   Admin      Probe
boot.web1                      probe      Healthy 5/5
boot.web2                      probe      Healthy 5/5
quit退出
命令行:
清除缓存
[root@localhost ~]# varnishadm ban req.url "~" /   #varnish启动
varnishadm  [-t   timeout ]    [-S 密钥文件]   [-T   address:port]   [-n  name]    [command]
#
-t   等待操作完成的时间
-S   认证的安全文件
-T    管理的接口和地址
-n   连接接口的名称
command   执行的命令
[root@localhost ~]# varnishadm -S /etc/vc -T 192.168.2.10:3500 stop
[root@localhost ~]# varnishadm -S /etc/vc -T 192.168.2.10:3500 start
[root@localhost ~]# varnishadm -S /etc/vc -T 192.168.2.10:3500 backend.list
Backend name                   Admin      Probe
boot.web1                      probe      Healthy 5/5
boot.web2                      probe      Healthy 5/5

varnishstat    #查看状态和参数
[root@localhost ~]# cd /usr/local/varnish/
[root@localhost varnish]# ls
bin         default.vcl  lib   share  varnish.pid                    _.vsm
cache.data  include      sbin  var    vcl_boot.1592884068.760178804
#_.vsm   是通过制定的配置文件启动后生成的文件
[root@localhost varnish]# cd /usr/local/varnish/var/varnish/localhost.localdomain/
[root@localhost localhost.localdomain]# ls
_.secret                       vcl_boot.1592794538.439760923  vcl_boot.1592882130.538364649
vcl_boot.1592623750.409803391  vcl_boot.1592794742.336751223  vcl_boot.1592882197.950655222
vcl_boot.1592623912.852447987  vcl_boot.1592794773.063064337  vcl_boot.1592882357.811198235
vcl_boot.1592626478.964962482  vcl_boot.1592881557.420217991  _.vsm
[root@localhost localhost.localdomain]# cp /usr/local/varnish/_.vsm ./
cp: overwrite ‘./_.vsm’? y 
#varnishstat这个命令只能查看到对应目录的_.vsm这个文件   所以需要把通过制定的配置文件生成的vsm文件复制到对应目录下  这样才能查看到当前这个配置文件的参数和状态
[root@localhost localhost.localdomain]# varnishstat

varnishlog 查看日志
varnishncsa 用来查看简单的日志

[root@localhost ~]# varnishlog -n /usr/local/varnish/ -w /usr/local/varnish/varnish.log
-n  代表工作目录
-w  代表日志生成的文件
#需要有台运行
客户端上访问:
[root@localhost ~]# curl 192.168.2.10
2222
[root@localhost ~]# curl 192.168.2.10
2222
varnish上另开终端:
[root@localhost varnish]# cd /usr/local/varnish/
[root@localhost varnish]# ls
bin         default.vcl  lib   share  varnish.log  vcl_boot.1592884068.760178804
cache.data  include      sbin  var    varnish.pid  _.vsm
[root@localhost varnish]# cat varnish.log 

varnishncsa
[root@localhost ~]# rm -rf /usr/local/varnish/varnish.log
[root@localhost ~]# varnishncsa -n /usr/local/varnish/ -w /usr/local/varnish/varnish.log
后台运行
客户端上访问:
[root@localhost ~]# curl 192.168.2.10
2222
[root@localhost ~]# curl 192.168.2.10
2222
varnish上另开终端:
[root@localhost varnish]# cd /usr/local/varnish/
[root@localhost varnish]# ls
bin         default.vcl  lib   share  varnish.log  vcl_boot.1592884068.760178804
cache.data  include      sbin  var    varnish.pid  _.vsm
[root@localhost varnish]# cat varnish.log 
[root@localhost varnish]# cat varnish.log 
192.168.2.100 - - [23/Jun/2020:12:14:19 +0800] "GET http://192.168.2.10/ HTTP/1.1" 200 5 "-" "curl/7.29.0"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值