varnish配置详解
能用到缓存的服务器的原因是,应用到了程序的局部性。
空间局部性:一个程序最近访问了一个空间,那么他周边的空间也将被访问。
时间的局部性:一条指令一段时间内被执行,之后的一段时间还会被执行。
衡量缓存的效率使用的缓存命中率:
文档命中率: 按照文档的数量进行衡量,10000 命中2000,就是1/5
字节命中率: 按照字节数量进行衡量,比如之前命中的两个为为100M,后面的八个为100K,那么按照数量来衡量命中率就最好用字节来衡量了。
缓存经历流程
浏览器缓存-->上游服务器缓存CDN-->反向代理的缓存-->真正原始服务器
varnish 的配置文件
1.用于定义各后端节点;
2.定义缓存机制
varnish的九个状态引擎
图:
每一个状态都有一个状态码,指明下一步如何进行。
vcl_pipe()表示不识别直接交给后端,只是在vcl_recv和后端主机之间建立了一个管道。
vcl_pass()表示略过,这是针对的不可缓存的对象
vcl_recv()是接受用户请求判断用户的请求首部,然后返回状态码pipe(不识别)|pass(不可缓存)|(error)(请求被拒绝)|lookup(交给hash查询)。
vcl_error()表示直接返回错误信息
vcl_hash():对用户的请求首部url做hash计算,查看是否有缓存。
vcl_hit ():表示内容被命中
vcl_miss():表示未命中
vcl_pass():如果是 对于不可缓存的对象,通过vcl_fetch建立客户端与后端主机,让后端主机直接给予应答,之后也不会给予缓存。
vcl_fetch():这是在后端主机更新缓存是时使用,1.如果请求是可缓存,并且规则允许缓存时,那么经过vcl_fetch,此时会给予链接至后端主机,由后端主机响应数据给客户端,然后本地缓存。2.如果请求是可以缓存的,但是我们本地规则设置不允许缓存的,我们给予建立后端链接,让客户端响应,本地不给于缓存。3.对于不可以缓存的,直接建立后端链接,让后端主机响应,本地不做缓存。
下载安装varnish包:
lftp172.16.0.1:/pub/Sources/6.x86_64/varnish> mget ./varnish* 881392 bytes transferred Total 4 files transferred lftp 172.16.0.1:/pub/Sources/6.x86_64/varnish> bye [root@localhost haproxy ]# ls varnish-docs-3.0.6-1.el6.x86_64.rpm //varnish的文件 varnish-3.0.6-1.el6.x86_64.rpm varnish-libs-3.0.6-1.el6.x86_64.rpm //varnish的库文件
安装生成文件:
配置文件:
这是关键配置文件,进程自己的工作属性
/etc/sysconfig/varnish
定义代理的工作属性
/etc/varnish/default.vcl
配置文件的修改
[root@localhost sysconfig ]# vim varnish # Maximum number of open files (for ulimit -n) 8 NFILES=131072 //可以打开的最大文件数 10 #Locked shared memory (for ulimit -l) 11 #Default log size is 82MB + header 12 MEMLOCK=82000 //日志的最大首部大小 15 NPROCS="unlimited" 66 VARNISH_LISTEN_PORT=6081 89 #VARNISH_STORAGE_SIZE=1G 90 VARNISH__MALLOC_SIZE=512M //指定存储的大小 91 # #Backend storage specification #VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}" //指定存储的类型 VARNISH_STORAGE="malloc,,${VARNISH_MALLOC__SIZE}" //这
里是使用内存的方式
1.自定义配置文件的名字
我们使用test.vcl 代替default.vcl
[root@localhost varnish ]# mv default.vcl test.vcl //我们还需要到进程配置文件的,修改默认的配置文件名 59 # #Main configuration file. You probably want to change it :) 60 #VARNISH_VCL_CONF=/etc/varnish/default.vcl 61 VARNISH_VCL_CONF=/etc/varnish/test.vcl //这样我们重启就可以是实现修改默认配置文件了 #service varnish restart
#但是缓存服务器一般不会重启,我们使用的方式是:
[root@localhost etc ]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 200 varnish> vcl.load t1 test.vcl 200 varnish> vcl.use t1 varnish> vcl.list 200 available 0 boot active
2.定义单个后端主机:
格式:
Backend nodename { .host = "ipaddr"; //分号结尾 .port = "port"; //点号开头 }
例如:
7 backend default {
8 .host = "172.16.249.248";
9 .port = "80";
10 }
3.定义deliver投递方式:
我们自己定义一个变量:set 设置自定义首部。 + 用于连接字符串。
这里我们的代理配置文件定义一个默认后端主机:
定义一个后端主机:然后开器deliver状态引擎。:
7 backend default { 8 .host = "172.16.249.220"; 9 .port = "80"; 10 } sub vcl_deliver { 116 if(obj.hits > 0) { 117 set resp.http.X-Cache = "HIT via" + " " + server.hostname; 118 } 119 else { 120 set resp.http.X-Cache ="MISS"; 121 } 122 return(deliver); 123 }
4.内置变量:
五类:
Req ,resp ,bereq ,beresp ,obj
请求类:
Sever.ip 服务端IP
Serve.hostname 主机名
Req.backend 指定对应主机名
Req.url 指定请求的地址
Req.http.header 指定请求http协议头部信息。
Req.quest指定请求方法
Req.http.x-forword-for 转发上一级的IP信息
Req.http
响应类:
Resp.response 响应给客户端的http信息
Resp.http.header 返回给客户端的http头部信息
Resp.status 响应的状态码
bereq由varnish向后端主机的请求类
beReq.url 指定请求的地址
beReq.http.header 指定请求http协议头部信息。
beReq.quest指定请求方法
由后端主机向varnish响应的变量
Beresp.request 指定请求的类型
Beresp.url 指定请求的路径
Beresp.http.header 请求的首部信息
Beresp.ttl 缓存的保留时长
关于获取内容的变量
Obj.status 请求状态码
Obj.ttl 缓存时间
Obj.hits 命中次数
5.VCL语法:
vcl是基于域的编程语言,支持算数运算和逻辑运算们支持正则表达式。支持set自定义变量,支持unset撤销变量,支持if条件判断,有内置的函数和变量;
保存于vcl配置文件中;此配置文件需要编译为二级制方式,才能使用。
后端节点backend name {}
代理缓存
Sub 来定义状态引擎。
是由manager进程调用gcc,编译然后交给子进程使用。
状态引擎有很大的相关性:return(X)定义退出状态,进而决定继续处理的下一个引擎。
vcl的语法格式:
1.注释:使用//, /*多行注释*/
2.sub $name 定义函数
3.不支持循环
4.支持条件判断
5.支持终止语句
6.域专用
7.操作符:=,==,~,!, 支持正则表达式
vcl内置函数:
Regsub(str,pattern,sub) 按照正则表达式,把str换成sub
Regsubball(str,regexp,sub) 全局】
Hash_data(str)
Purge:从缓存中挑选出对象并删除
return()
例如:vcl-recl 可以返回pass,pipe,lookup ,error
6.if语句的使用语法结构:
语法的使用:
If 语句 单分支{
}
多分支
If(condition){
…;
}
Else{
…;
}
7.定义某类内容被缓存:
注意这里面模式匹配的内容要用到引号引起来。语法把他们当做语法。
38 if (req.http.Authorization || req.http.Cookie) { 39 /* Not cacheable by default */ 40 return (pass); 41 } 42 if (req.url ~"\.(jpg|jpeg|png|gif)$"){ //如果是以这些结尾 43 if(req.http.Cookie){ //如果有cookie 44 unset req.http.Cookie; //清除cookie 45 } 46 } 47 return (lookup); //返回查询状态码 48 }
我下线httpd ,查看是否缓存下来
8.基于ACL的支持访问控制机制:
使用格式:
Acl name {
"ip";
"net"; //注意在;这里如果是一个网段掩码要在外面 "172.16.0.0"/16;
}
这种情况,我们一般用在特殊,需要控制的范围。例如:清除缓存。
9.error内置命令的使用
Error code 直接生成一个响应页面,这个页面可以是完成的,也可以是错误的。
常用code有 200 405 " "
10.清除缓存purge的设定
1.首先设置访问控制,只允许本机和IP172.16.249.141访问。
acl purges { 12 "127.0.0.1"; 13 ="localhost"; 14 "172.16.249.141"; 15 }
2.配置purge规则
自定义一个请求方法比如是PURGE。
如果用用户是通过我们定义的主机使用的purge方法,允许清除对应的缓存,如果不是返回错误页面。
如果没有命中要清除的缓存,也返回提示错误页面
backend default { 8 .host = "172.16.249.248"; 9 .port = "80"; 10 } #对purges设置权限 11 acl purges { 12 "127.0.0.1"; 13 "localhost"; 14 "172.16.249.141"; 15 } 23 sub vcl_recv { 24 if (req.restarts == 0) { 25 if (req.http.x-forwarded-for) { 26 set req.http.X-Forwarded-For = 27 req.http.X-Forwarded-For + ", " + client.ip; 28 }else { 29 set req.http.X-Forwarded-For = client.ip; 30 } 31 } #定义请求方法,允许使用PURGE 32 if (req.request != "GET" && 33 req.request != "HEAD" && 34 req.request != "PUT" && 35 req.request != "POST" && 36 req.request != "TRACE" && 37 req.request != "OPTIONS" && 38 req.request != "DELETE" && 39 req.request != "PURGE") { 40 /* Non-RFC2616 or CONNECT which is weird. */ 41 return (pipe); 42 } #定义请求方法,允许使用PURGE 43 if (req.request != "GET" && req.request !="HEAD" && req.request != "PURGE") { 44 /* We only deal with GET and HEAD by default */ 45 return (pass); 46 } 47 if (req.http.Authorization || req.http.Cookie) { 48 /* Not cacheable by default */ 49 return (pass); 50 } 51 if (req.request =="PURGE") { 52 if (!client.ip ~purges){ 53 error 405 "forbidding"; 54 } 55 } 56 if (req.url ~ "\.(jpg|jpeg|png|gif)$"){ 57 if(req.http.Cookie){ 58 unset req.http.Cookie; 59 } 60 } 61 return (lookup); 62 }#定义命中状态引擎,命中执行purge函数 92 sub vcl_hit { 93 if (req.request == "PURGE"){ 94 purge; 95 error 200 "finished"; 96 } 97 }#定义非命中状态引擎, 错误引擎 102 subvcl_miss { 103 if (req.request == "PURGE"){ 104 purge; 105 error 404 "no cache"; 106 } 107 }
11.自定义那些内容可以缓存,以及缓存时长
124 sub vcl_fetch { 125 if (req.url ~"\.(jpg|jpeg|png|gif)$"){ 127 set beresp.ttl = 3600 s; 128 return(deliver);} 129 if (req.url ~ "\.(php|cgi)$"){ 130 set beresp.ttl = 0 s; } 131 return(deliver); 132 }
12.健康状态检查:
.probe = { //可以单独定义,也可以在backend中定义 .url =# //指明路径 .request =# //定义请求格式 .windowns =# //基于最近多少次检查,是失败还是成功。这里是8次 .threshold = # 这里是必须成功了5次才认为是健康的。 .initial = # 成功多少次,才把后端主机设置为健康状态。 .expected_response=# //指定的时间 .interval = //间隔时间 .timeout = } 例如: probe dynamic { .url = "/index.html"; .interval = 5s; .timeout = 1s; .expected_response= 200; }
13.定义缓存的负载均衡和动静分离
backend app1 { .host = "172.16.11.11"; .port = "80"; } backend app2 { .host = "172.16.11.12"; .port = "80"; } backend web1 { .host = "172.16.11.13"; .port = "80"; } backend web2 { .host = "172.16.11.14"; .port = "80"; } director apps random { #定义一个后端服务器组,实现负载均衡效果 { .backend = app1; #调用前面已定义过的后端主机 .weight = 2; #设置权重 } { .backend = app2; .weight = 2; } } director webs random { #定义后端静态服务器组,实现负载均衡效果 { .backend = web1; .weight = 2 ; } { .backend = web2; .weight = 2 ; } } sub vcl_recv { #定义引用规则 if (req.url ~ "\.php(\?\.*|$)") { set req.backend = apps; }else { set req.backend = webs; } return(lookup);
varnish管理命令
跟随varnish会一起安装一些方便的调试工具,用好这些工具,对你更好的应用varnish有很大的帮助。
varnishncsa(以 NCSA 的格式显示日志)
通过这个命令,可以像类似于 nginx/apache一样的显示出用户的访问日志来。
varnishlog(varnish详细日志)
如果你想跟踪varnish处理每个请求时的详细处理情况,可以使用此命令。
直接使用这个命令,显示的内容非常多,通常我们可以通过一些参数,使它只显示我们关心的内容。
-b \\只显示varnish和backend server之间的日志,当您想要优化命中率的时 候可以使用这个参数。
-c \\和-b差不多,不过它代表的是 varnish和 client端的通信。
-i tag \\只显示某个 tag,比如“varnishlog �Ci SessionOpen”将只显示新会话,注意,这个地方的tag名字是不区分大小写的。
-I \\通过正则表达式过滤数据,比如“varnishlog -c -i RxHeader -I Cookie”将显示所有接到到来自客户端的包含 Cookie 单词的头信息。
-o \\聚合日志请求 ID
varnishlog -c -o /auth/login 这个命令将告诉您来自客户端(-c)的所有包含”/auth/login” 字段(-o)请求。
varnishlog -c -o ReqStart 192.168.1.100 只跟踪一个单独的client请求
varnishtop
您可以使用varnishtop 确定哪些URL经常被透传到后端。
适当的过滤使用 �CI,-i,-X 和-x 选项,它可以按照您的要求显示请求的内容,客
户端,浏览器等其他日志里的信息。
varnishtop -i rxurl \\您可以看到客户端请求的 url次数。
Varnishtop -i txurl \\您可以看到请求后端服务器的url次数。
Varnishtop -i Rxheader -I Accept-Encoding \\可以看见接收到的头信息中有有多少次
包含Accept-Encoding。
varnishstat
显示一个运行varnishd实例的相关统计数据。
Varnish 包含很多计数器,请求丢失率,命中率,存储信息,创建线程,删除对象等,几乎所有的操作。通过跟踪这些计数器,可以很好的了解varnish运行状态。
varnishadm
通过命令行,控制varnish服务器。可以动态的删除缓存,重新加载配置文件等。
管理端口有两种链接方式:
1,telnet方式,可以通过telnet来连接管理端口.如:"telnet localhost 6082"
2,varnishadm方式,可以通过varnish自带的管理程序传递命令.如: varnishadm -n vcache -T localhost:6082 help
动态清除缓存
varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 ban.url /2011111.png
其中:ban.url 后的路径一定不要带abc.xxx.com域名之类的,否则缓存清除不了。
清除包含某个子目录的URL地址:
/usr/local/varnish/bin/varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 url.purge /a/
不重启加载配置文件
登陆到管理界面
/usr/local/varnish/bin/varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
加载配置文件
vcl.load new.vcl /etc/varnish/default.vcl
编译出错的话会有提示,成功会返回200
加载新配置文件
vcl.use new.vcl
此时新的配置文件已经生效!