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 –i 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经常被透传到后端。
适当的过滤使用 –I,-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
此时新的配置文件已经生效!
转载于:https://blog.51cto.com/guanqianjian/1604510