五、varnish的使用
(一)初步使用
1、编辑varnish的配置脚本文件:
从文件中可以看出,对进程的资源限制基本上都是被打开了,不做限制
如果要使用内存做缓存存储类型,则须按下面修改配置文件:
VARNISH_STORAGE_SHM=64M
#VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}"(删除或注释掉原来的存储类型配置)
VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SHM}" (添加内存存储类型配置)
为了能够更灵活地配置配置文件,其他配置都使用/etc/varnish/default.vcl来配置,二不用命令行工具varnishadm
2、定义好varnish工作特性配置文件后,就可以启动varnish服务了:
[[email protected] ~]# service varnish start Starting Varnish Cache: [ OK ]
监听的端口有三个,6082是管理接口的监听端口,80是对远程客户端提供服务的监听端口:
[[email protected] ~]# ss -tnlp | grep varnish LISTEN 0 10 127.0.0.1:6082 *:* users:(("varnishd",6033,6)) LISTEN 0 128 :::80 :::* users:(("varnishd",6034,8)) LISTEN 0 128 *:80 *:* users:(("varnishd",6034,7))
3、修改配置文件与varnishadm结合使用更换缓存存储策略
node2主机配置httpd服务:
# yum install -y httpd Installed: httpd.x86_64 0:2.2.15-39.el6.centos Complete! [[email protected] ~]# vim /var/www/html/index.html <h1> web1</h1> [[email protected] ~]# service httpd start Starting httpd: [ OK ]
varnish主机也能获取node2主机的web网页:
[[email protected] ~]# curl 172.16.20.200 <h1> web1</h1>
配置文件:
修改后端监听地址由127.0.0.1改为提供web服务的主机地址,其他的暂时不需要改动
[[email protected] ~]# vim /etc/varnish/default.vcl backend default { .host = "172.16.20.200"; .port = "80"; } [[email protected] ~]# service varnish restart Stopping Varnish Cache: [FAILED] Starting Varnish Cache: [ OK ]
连接到varnish的CLI:
[[email protected] ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 …… varnish> ping 200 PONG 1433559864 1.0
有PONG回应,表示服务器处于正常状态。
输入help能给出显示所有可用的命令:
varnish> help 200 help [command] ping [timestamp] ——测试服务器是否处于正常状态 auth response quit banner ——显示banner信息 status ——显示状态信息 start ——启动子进程 stop ——停止子进程 vcl.load <configname> <filename> ——装载编译配置文件为一个vcl,取名为configname vcl.inline <configname> <quoted_VCLstring> vcl.use <configname> ——使用configname的配置 vcl.discard <configname> ——删除configname配置 vcl.list ——显示所有可用的vcl vcl.show <configname> ——显示对应configname的vcl (active)的配置 param.show [-l] [<param>] param.set <param> <value> panic.show panic.clear storage.list backend.list backend.set_health matcher state ban.url <regexp> ban <field> <operator> <arg> [&& <field> <oper> <arg>]... ban.list
缓存功能测试:
①、添加虚拟主机,提供httpd服务:
[[email protected] ~]# yum install -y httpd [[email protected] ~]# vim /var/www/html/index.html <h1>web1</h1>
②、修改varnish配置文件,使缓存的服务器内容指向新主机node1的web1
[[email protected] ~]# vim /etc/varnish/default.vcl backend default { .host = "172.16.20.150"; .port = "80"; }
③、在varnish主机上编译配置文件,并启用
[[email protected] ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 varnish> vcl.load test1 default.vcl 200 VCL compiled. varnish> vcl.use test1 200
⑤、查看缓存配置效果
从上面的过程可以看出,varnish的使用流程是:
安装varnish后会生成两类(两个)主要配置文件:一种是定义varnish程序自己的工作特性的配置文件,地址为/etc/sysconfig/varnish ,一种是配置varnish如何为需要缓存的服务器工作的配置文件/etc/varnish/default.vcl。
安装varnish、varnish-libs--> 修改/etc/sysconfig/varnish ,定义好varnish自己的工作状态,为向其他服务器提供服务做好准备 --> 在需要缓存的服务器准备好后,修改/etc/varnish/default.vcl ,设定缓存工作的策略 --> 通过varnishadm CLI命令进行 vcl.load编译,vcl.use使用,平滑非重启式切换缓存工作策略(即原来的缓存不会立即失效,而是正常的过期失效并更换 --> 修改缓存策略,varnishadm编译使用……
六、varnish的深入使用
(一)sub 子程序及if条件判断:
[[email protected] ~]# vim /etc/varnish/default.vcl sub vcl_hit { if (obj.hits>0) { set resp.http.X-Cache = "HIT"; } else { set resp.http.X-Cache = "MISS"; } return (deliver); }
上面语句的意思是:如果某个缓存的命中数大于0,则设定内置变量resp.http.X-Cache的值为 “HIT”,否则其值为“MISS”。判断处理完后转到deliver引擎构建响应报文。
[[email protected] ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 varnish> vcl.load test2 default.vcl 106 Message from VCC-compiler: ‘resp.http.X-Cache‘: cannot be set in method ‘vcl_hit‘. At: (‘input‘ Line 71 Pos 21) set resp.http.X-Cache = "HIT"; --------------------#################--------- Running VCC-compiler failed, exit 1 VCL compilation failed
如果配置文件出现了错误,则vcl.load时会报错,这时重新修改配置文件即可
[[email protected] ~]# vim /etc/varnish/default.vcl sub vcl_deliver { if (obj.hits>0) { set resp.http.X-Cache = "HIT"; } else { set resp.http.X-Cache = "MISS"; } return (deliver); } [[email protected] ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 varnish> vcl.load test2 default.vcl 200 VCL compiled. varnish> vcl.use test2 200 varnish> vcl.list 200 available 0 boot available 0 test1 active 2 test2
vcl.list查看可用的vcl,现在使用的缓存策略是test2
从上面的简单例子里可以看出,varnish的重点是在配置缓存工作策略,而缓存策略的配置是在各引擎中设定的。设定时就是使用条件判断语句进行判断后,设定各种内置的变量,从而通过这些变量进行工作。
可使用的条件判断语句有:
单分支:
if (CONDITION) {
...;
}
双分支:
if (CONDITION) {
...;
} else {
...;
}
多分支:
if (CONDITION1) {
...
} elseif (CONDITION2) {
...
} else {
...
}
if(obj.hits>0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache= "MISS";
}
可使用的变量有:
1、全局变量global variables:
now:现在的时间,单位是秒,从新纪元开始算起。可以用字符串上下文限定格式
2、backend declaration声明中可用变量:
.host:后端服务器的主机名或者IP地址
.port:后端服务器提供的服务名或者端口号
3、处理请求时(recv、hash、pass、pipe)可用变量:
(缩进的表示不是特别重要的变量)
client.ip:客户端的IP地址
client.identity:客户端标识符,用于客户调度时的负载均衡。(一般现在用不上)
server.hostname:varnish服务器的主机名
server.identity:varnish服务器的标识符,可通过-i设定,如果没有通过-i设定,则会在通过-n设定
servier.ip:与客户端建立连接时所使用的套接字中的IP地址
server.port:与客户端建立连接时所使用的套接字中的端口号
req.request:请求类型,如GET、HEAD
req.url:被客户端请求的url
req.proto:客户端请求所使用的HTTP协议版本
req.backend:需要后端响应请求时所使用的后端主机,一般在recv中就设置好了
req.backend.healthy:后端服务器是否处于健康状态,只有设置了健康探测动作后这个变量才有使用的意义
req.http.HEADER:引用请求报文中指定的首部的值,如req.http.host表示引用请求报文首部host(服务器主机名)的值
req.hash_always_miss:是否强迫对此请求做缓存miss处理,如果设定值为“true”,则varnish每次都会忽略缓存内容,而直接到后端服务器获取信息
req.hash_ignore_busy:当查找缓存时忽略繁忙的缓存内容而不去查询
req.can_gzip:客户端是否接受gzip压缩编码格式的报文
req.restarts:此请求被重启的次数(url改写引起。当重启次数高于一定值时,varnish内生机制会放弃此次请求的缓存查询)
req.grace:设定宽限期的值
4、向后端服务器发起请求时常用的变量(本地无缓存或pass、pipe模式时使用)
bereq.request:请求的类型,如GET、HEAD
bereq.url:请求的url
bereq.proto:与后端服务器通信时使用的HTTP协议版本
bereq.http.HEADER:向后端服务器发请求时调用我们感兴趣的首部,与处理客户端请求时类似
bereq.connect.timeout:等待与后端建立连接的超时时长,单位为秒,发出建立连接请求后多少秒还没有收到建立连接的响应就不会再等待回应
还有其他变量,但不常用,一般都不设置,这里就不列了
5、从后端服务器请求的对象取回但还没有存入本次缓存时可用的变量(这时还没有构建响应报文),也即是在vcl_fetch中可用的变量:
beresp.do_stream:从后端接收到报文后直接将其封装响应给客户,而不是在接收到本次请求的所有响应报文后再封装响应给客户。当后端响应报文有10M时这个选项特别有效。
beresp.do_gzip:布尔型值(值为yes|no),收到后端响应的对象后是否先压缩再存储在缓存,如果压缩了,而客户端浏览器识别不了gzip编码格式的报文,则客户端是无法获得请求网页或数据的。默认为no
beresp.do_gunzip:布尔型值(值为yes|no),收到后端响应的对象后是否先解压缩再存储在缓存,解压缩是为了不能接受gzip压缩的客户端时可用使用的,如果客户端指定了要gzip编码格式的报文,则不应该解压缩。默认为no
beresp.http.DEADER:响应报文的特定头部
beresp.proto:后端服务器响应时所使用的HTTP协议版本
beresp.status:后端服务器响应给varnish的HTTP状态码,200,404等
beresp.response:后端服务器响应给varnish的HTTP状态原因短语
beresp.ttl:响应对象的剩余的生存时长,单位为秒,此值可修改
beresp.backend.name:发送此次响应报文的后端服务器的主机名
beresp.backend.ip:发送此次响应报文的后端服务器的IP
beresp.backend.port:发送此次响应报文的后端服务器的端口
beresp.storage:强制varnish将此对象缓存存储到特定的存储后端,用得不多
6、缓存对象存入cache之后可用的变量(在vcl_hit或vcl_error中使用,大部分只读):
obj.proto:缓存对象取回时所使用的HTTP协议版本
obj.status:后端服务器响应此缓存对象的状态码
obj.response:后端服务器响应此缓存对象的状态码的原因短语
obj.ttl:此缓存对象剩余生存时长,单位为秒,可修改
obj.hits:此缓存的已经被发送给客户端的次数的近似值(即命中次数),0表示无命中,在vcl_deliver中也可用
obj.http.HEADER:来自于后端服务器的响应报文的指定头部的值
7、在决定对请求键做hash计算时可用的变量
req.hash:指向某个缓存对象的hash key,在从缓存中读和向缓存中写时需要用到
8、在为客户端准备响应报文时可用的变量(vcl_deliver中使用)
resp.proto:构建响应报文时使用的HTTP协议版本
resp.status:构建响应报文时响应给客户端的状态码
resp.response:构建的响应报文的状态码的原因短语
resp.http.HEADER:构建的响应报文的特定头部
9、用于对后端主机健康状态监测使用的变量:
.probe中的探测指令常用的有:
(1) .url:指定探测后端主机健康状态时请求的URL,默认为“/”;
(2) .request: 探测后端主机健康状态时所请求内容的详细格式,.request中定义的路径优先级高于.url中定义的路径,因此定义后,它会替换.url指定的探测方式;比如:
.request =
"GET /.healthtest.html HTTP/1.1"
"Host: www.magedu.com"
"Connection: close";
(3) .window:设定在判定后端主机健康状态时基于最近多少次的探测进行,默认是8;
(4) .threshold:门槛数,在.window中指定的次数中,至少有多少次是成功的才判定后端主机正健康运行;默认是3;
(5) .initial:Varnish启动时对后端主机至少需要多少次的成功探测,默认同.threshold;
(6) .expected_response:期望后端主机响应的状态码,默认为200;
(7) .interval:探测请求的发送周期,设置得过长,移除故障后端的时间就越长,默认为5秒;
(8) .timeout:每次探测请求的过期时长,默认为2秒;
(二)应用实例
1、vcl_recv子进程的启用及客户ip的传送:
vcl_recv子进程是接受报文的第一站,重要引擎调度及分配是在这一子进程设置得。
启用vcl_recv子进程前访问日志未记录客户端地址,而全是缓存服务器地址:
[[email protected] ~]# tail -3 /var/log/httpd/access_log 172.16.20.100 - - [06/Jun/2015:20:18:37 +0800] "GET / HTTP/1.1" 200 14 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36" 172.16.20.100 - - [06/Jun/2015:20:18:37 +0800] "GET /favicon.ico HTTP/1.1" 404 288 "http://172.16.20.100/" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36" 172.16.20.100 - - [06/Jun/2015:20:56:19 +0800] "GET / HTTP/1.1" 200 23 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36"
修改配置文件,启用sub vcl_recv子进程的内容、后端服务器不变:
[[email protected] ~]# vim /etc/varnish/default.vcl backend default { .host = "172.16.20.150"; .port = "80"; } sub vcl_recv { if (req.restarts == 0) { if (req.http.x-forwarded-for) { set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; } else { set req.http.X-Forwarded-For = client.ip; } } if (req.request != "GET" && req.request != "HEAD" && req.request != "PUT" && req.request != "POST" && req.request != "TRACE" && req.request != "OPTIONS" && req.request != "DELETE") { /* Non-RFC2616 or CONNECT which is weird. */ return (pipe); } if (req.request != "GET" && req.request != "HEAD") { /* We only deal with GET and HEAD by default */ return (pass); } if (req.http.Authorization || req.http.Cookie) { /* Not cacheable by default */ return (pass); } return (lookup); }
[[email protected] ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 varnish> vcl.load t1 default.vcl 200 VCL compiled. varnish> vcl.use t1 200 varnish>
然后修改后端服务器日志记录格式并重载配置:
[[email protected] ~]# vim /etc/httpd/conf/httpd.conf LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined CustomLog logs/access_log combined [[email protected] ~]# service httpd reload Reloading httpd:
强制刷新网页后查看后端服务器日志:
2、禁止某个IP客户端访问(以172.16.250.248为例)
修改配置文件,在sub vcl_recv段的return (lookup);语句之前添加如下条件控制语句:
sub vcl_recv { if (client.ip == "172.16.250.248") { error 404 "You are Forbidden!"; } return (lookup); }
[[email protected] ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 varnish> vcl.load t2 default.vcl 200 VCL compiled. varnish> vcl.use t2 200 varnish>
3、sub vcl_hash说明:
先对请求的url做 hash计算,然后做条件判断:
如果请求报文中的服务器主机名不为空,则对该主机名进行hash计算;否则对varnish服务器的ip地址做hash计算。最后返回重新做hash模式。
一般情况下都不需要启用这项子进程,让系统采用默认配置就行
sub vcl_hash { hash_data(req.url); if (req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); } return (hash); }