设为首页 收藏本站
查看: 2211|回复: 0

[经验分享] varnish+nginx实现单双web服务器缓存

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2014-9-28 09:42:36 | 显示全部楼层 |阅读模式
实验目的:
varnish利用实现对后端单双静态web服务器的缓存
varnish包的下载路径:http://repo.varnish-cache.org/redhat/varnish-3.0/el6 可以下载到varnish的rpm包
需要下载的有:
varnish-3.0.5-1.el6.x86_64
varnish-docs-3.0.5-1.el6.x86_64
varnish-libs-3.0.5-1.el6.x86_64
varnish的官网地址:https://www.varnish-cache.org/
实验环境:
web1:172.16.18.3            Nginx
web2:172.16.17.12          Nginx
varnish:172.16.18.1         Varnish
实验内容:
一,安装varnish包,配置web服务器
1
2
3
4
5
6
7
8
9
10
[iyunv@node1~]# rpm -ql varnish     
/etc/rc.d/init.d/varnish              #varnish的启动程序     
/etc/rc.d/init.d/varnishlog           #日志     
/etc/rc.d/init.d/varnishncsa          #日志     
/etc/sysconfig/varnish                #配置文件,varnish定义自身属性     
/etc/varnish                          #配置文件目录     
/etc/varnish/default.vcl              #默认配置文件,定义后端节点的     
/usr/bin/varnish_reload_vcl           #加载vcl,     
/usr/bin/varnishadm                   #客户端程序     
/usr/bin/varnishstat                  #状态监控



二,编辑配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[iyunv@node1 ~]# vim /etc/sysconfig/varnish
NFILES=131072
MEMLOCK=82000
NPROCS="unlimited"
RELOAD_VCL=1                                                        #是否重载VCL文件
## Alternative 3, Advanced configuration
VARNISH_VCL_CONF=/etc/varnish/default.vcl              #vcl文件路径
VARNISH_LISTEN_PORT=80                                     #varnish自己工作于那个端口。默认是6081
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1       #管理接口
VARNISH_ADMIN_LISTEN_PORT=6082                    #管理接口监听端口
VARNISH_SECRET_FILE=/etc/varnish/secret                #密钥文件
VARNISH_MIN_THREADS=50                                    #最少空闲线程
VARNISH_MAX_THREADS=1000                                #最多启动线程
VARNISH_THREAD_TIMEOUT=120                            #work超时时长
#VARNISH_STORAGE_FILE=/var/lib/varnish/varnish_storage.bin        #存储文件
VARNISH_STORAGE_SIZE=64M                                                    #存储文件文件大小
#VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}"    #存储方式file
VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SIZE}"     #基于内存方式
VARNISH_TTL=120
DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \
             -f ${VARNISH_VCL_CONF} \
             -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \
             -t ${VARNISH_TTL} \
             -w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \
             -u varnish -g varnish \
             -S ${VARNISH_SECRET_FILE} \
             -s ${VARNISH_STORAGE}"





1
2
3
4
5
[iyunv@node1 ~]# vim /etc/varnish/default.vcl
backend default {
  .host = "172.16.18.3";
  .port = "80";
}



此时varnish就已经可以启动了。下来就是最重要的编写vcl文件。
那么我们就应该熟悉这张表,每一个状态引擎所对应的变量
1.png
简单介绍一下vcl的语法
VCL的设计参考了C和Perl语言,因此,对有着C或Perl编程经验者来说,其非常易于理解。其基本语法说明如下:
(1)//、#或/* comment */用于注释
(2)sub $name 定义函数
(3)不支持循环,有内置变量
(4)使用终止语句,没有返回值
(5)域专用
(6)操作符:=(赋值)、==(等值比较)、~(模式匹配)、!(取反)、&&(逻辑与)、||(逻辑或)
编译vcl文件中状态引擎的顺序我们按照默认配置文件的顺序来,此顺序也符合请求处理的基本顺序,当然,为了配合实验也会有些改动。我们来看一张图,可以明确的明白请求的过程:
2.png
1,首先我们来编写vcl_recv段,
vcl_recv作为进入varnish对请求报文解码后第一个子例程,可以在此处做访问控制,是否查询缓存,以及无法识别的数据的判定。
首先对default.vcl文件复制一份重新改名为test1.vcl
acl purgers {                                        #定义一个acl
"127.0.0.1";
"172.16.0.0"/16;
}
sub vcl_recv {
    if (req.url ~ "^/test.html$") {             #请求首部的url匹配到test.html,
                return(pass);                       #跳过缓存
        }
    if
    if (req.request != "GET" &&             #请求方法不是已知的这7中则发到pipe上去
       req.request != "HEAD" &&
       req.request != "PUT" &&
       req.request != "POST" &&
       req.request != "TRACE" &&
       req.request != "OPTIONS" &&
       req.request != "DELETE") {
       return (pipe);
       }
    if (req.request != "GET" && req.request != "HEAD") {         #不是获取资源的全部跳过缓存,减少无用缓存查询
       return (pass);
     }
    if (req.request == "PURGE") {               
        if (!client.ip ~ purgers) {                                                   #请求IP不在ACL中定义,则发挥405错误页。
            error 405 "Method not allowed";
          }
        return (lookup);
    }
    return (lookup);
}
那么此时如何加载这个test1让他生效呢?
第一修改配置文件。
第二,利用varnishadm客户端工具。
varnishadm
[root@node1 ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082         #进入到管理工具     
200      
-----------------------------     
Varnish Cache CLI 1.0     
-----------------------------     
Linux,2.6.32-431.el6.x86_64,x86_64,-sfile,-smalloc,-hcritbit     
varnish-3.0.5 revision 1a89b1f     
Type 'help' for command list.     
Type 'quit' to close CLI session.     
varnish> vcl.load test1 test1.vcl                                                                    #加载vcl文件

200
VCL compiled.
varnish> vcl.list
200
active 2 boot
available 0 test1
varnish> vcl.use test1
200
varnish> vcl.list
200
available 2 boot
active 0 test1
这样就设定成功了。
为了显示效果我们来配置一下deliver段,给客户端返回时候匹配到缓存信息,以便我我们来查看实验结果。
sub vcl_deliver {
        if (obj.hits > 0) {                                                                        #判断条件缓存匹配次数大于0
                set resp.http.X-Cache = "HIT via" + " " + server.hostname;    #添加HIT via
        } else {
                set resp.http.X-Cache = "MISS via" + " " + server.hostname;   #没有匹配到则添加MISS via
        }
}
访问缓存172.16.18.1.第一次是miss via 之后的访问在缓存有效期内都是HIT via
3.png
当访问test.html是会被vcl_recv定义的pass匹配到,直接跳过缓存,所以X-cache状态一直是MISS via
4.png
2,编辑vcl_hash,自定义hash生成时的数据来源。
sub vcl_hash {
   hash_data(req.url);                   #依据req.url来匹配
if (req.http.host) {
   hash_data(req.http.host);          #请求首部的host来缓存
   } else {
   hash_data(server.ip);
   }
   return (hash);
}
3,编辑vcl_hit,从缓存中查找到缓存对象时要执行的操作
sub vcl_hit {                           
    if(req.request == "PURGE"){        #当进入缓存后清理缓存对象,返回Purged;
        purge;
        error 200 "Purged";
        }
}
非pipe请求必经过hit,miss,pass,这三条任意一条,所以也要在其他两路做purge匹配。
4,vcl_miss ,从缓存中查找不到缓存对象时要执行的操作;
sub vcl_miss {               
    if (req.request == "PURGE") {                如果直接不经过缓存,匹配到了PURGE,则返回404说没有进入缓存,否则发往fetch
        error 404 "Not in cache";
}
    return (fetch);
}
5,vcl_pass,用于将请求直接传递至后端主机
vcl_pass {
if (req.request == "PURGE") {              #如果直接是pass,跳过缓存,且匹配到PURGE,
    error 502 "PURGE on a passed object";   
}
    return (pass);
}
6,vcl_fetch,是在请求从后端被成功接收后调用的,可以使用req,bereq,beresp.
可在此处定义cache的缓存有效时长
sub vcl_fetch {
    set beresp.ttl = 360s;                             #修改缓存时长为360s,
    if (req.url ~ ".[jpg|gif|png]$"){                #图片文件缓存时长1h
        set beresp.ttl = 1h;
    }
    if (beresp.status != 200){                        #backend返回状态码不是200,则不缓存数据
        return (hit_for_pass);
    }
    return (deliver);
}
6,sub vcl_deliver ,将用户请求的内容响应给客户端时用到的方法;deliver,在recv之后我们就用过,在里边添加了一个相应给用户的X-cache,是否用到了缓存。复制下来!完善一下!
sub vcl_deliver {
        if (obj.hits > 0) {                                          
                set resp.http.X-Cache = "HIT via" + " " + server.hostname;   
        } else {
                set resp.http.X-Cache = "MISS via" + " " + server.hostname;   
        }
        set resp.http.host = server.hostname;
        retuen (deliver);
}
7,sub vcl_pipe {
    return (pipe);
}
到此一个简单的vcl功能就写好了。
先请求一下curl -X PURGE http://172.16.18.1/index.html
[root@node3 html]# curl -X PURGE http://172.16.18.1/index.html     
<html>     
<head><title>405 Not Allowed</title></head>             #发现和我们定义的Method not allowed不一样,那是为什么呢?

<body bgcolor="white">   
<center><h1>405 Not Allowed</h1></center>     
<hr><center>nginx/1.6.2</center>     
</body>     
</html>

经过查看vcl_recv段发现,我们在PURGE之上就将不是定义的方法送到了pipe.无法到达PURGE.修改如下。将PURGE写在方法判断之前
sub vcl_recv {
    if (req.url ~ "^/test.html$") {         
                return(pass);                     
        }
    if (req.request == "PURGE") {               
        if (!client.ip ~ purgers) {                                                            
            error 405 "Method not allowed";
          }
        return (lookup);
    }
    if (req.request != "GET" &&                       
       req.request != "HEAD" &&
       req.request != "PUT" &&
       req.request != "POST" &&
       req.request != "TRACE" &&
       req.request != "OPTIONS" &&
       req.request != "DELETE") {
       return (pipe);
       }
    if (req.request != "GET" && req.request != "HEAD") {                       
       return (pass);
     }
    return (lookup);
}
[root@node3 html]# curl -X PURGE http://172.16.18.1/index.html     
<?xml version="1.0" encoding="utf-8"?>     
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"     
"
http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">     
<html>     
<head>     
<title>404 Not in cache</title>     
</head>     
<body>     
<h1>Error 404 Not in cache</h1>     

Not in cache

<h3>Guru Meditation:</h3>     

XID: 506876240

<hr>     

Varnish cache server

</body>     
</html>

这下和我们定义的一样的,看来还得注意判断的先后次序。
下边我们来定义一下有cookie的文件走向。
首先在vcl_resv添加
if (!(req.url ~ "wp-(login|admin)")) {                #所有有cookie的请求都不查缓存
     unset req.http.cookie;
  }
在vcl_fetch中定义抹除cookie           
sub vcl_fetch {
  if (!(req.url ~ "wp-(login|admin)")) {
      unset beresp.http.Set-Cookie;
   }
}
三,后端主机的健康检测
backend web1 {
    .host = "172.16.18.3";
    .port = "80";
    .probe = {
        .url = "/index.html";            #探测什么文件
        .interval = 1s;                     #几秒探测一次
        .window = 5;                      #失败探测多少次
        .threshold = 2;                   #成功探测多少次
}
}
在varnishadm中查看
varnish> backend.list
200
Backend name Refs Admin Probe
default(172.16.18.3,,80) 8 probe Healthy 5/5      
四,varnish使用多台后端主机
Varnish中可以使用director指令将一个或多个近似的后端主机定义为一个逻辑组,并可以指定的调度方式(也叫挑选方法)来轮流将请求发送至这些主机上。不同的director可以使用同一个后端主机,而某director也可以使用“匿名”后端主机(在director中直接进行定义)。每个director都必须有其专用名,且在定义后必须在VCL中进行调用,VCL中任何可以指定后端主机的位置均可以按需将其替换为调用某已定义的director。
注意:当使用自定义的主机时一定要在vcl_recv中指定使用哪个主机,
backend web1 {
    .host = "172.16.18.3";
    .port = "80";
    .probe = {
        .url = "/index.html";           
        .interval = 1s;                  
        .window = 5;                     
        .threshold = 2;                 
}
backend web2 {
    .host = "172.16.18.3";
    .port = "80";
    .probe = {
        .url = "/index.html";         
        .interval = 1s;   
.window = 5;
        .threshold = 2;                 
}
director webservers round-robin {
  {.backend = web1;}
  {.backend = web2;}
}
vcl_recv {                                                        添加下边段落
set req.backend = webservers;                        放在最前边   
}

}
下来访问172.16.18.1验证有没有将请求在两个web服务器上轮询,
5.png
6.png
可以看到请求的test.html是轮询的,为什么不请求172.16.18.1呢,应为172.16.18.1有缓存,看不到效果。
varnish的实验就到此了。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-25455-1-1.html 上篇帖子: varnish搭建 下篇帖子: centos6.5 64位上haproxy安装 web服务器
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表