首页 > 代码库 > varnish简单学习

varnish简单学习

操作系统:redhat5.5

前端服务器:varnish cache 2.1.5 监听端口8080

后端服务器:tengine 1.4.6 监听端口80


接着,建立varnish用户以及用户组,并且创建Varnish缓存目录和日志目录:
[root@varnish-server ~]#useradd  -s /sbin/nologin varnish
[root@varnish-server ~]#mkdir /data/varnish/cache
[root@varnish-server ~]#mkdir /data/varnish/log
[root@varnish-server ~]#chown -R varnish:varnish  /data/varnish/cache
[root@varnish-server ~]#chown -R varnish:varnish  /data/varnish/log

编译安装pcre

[root@varnish-server ~]#tar zxvf pcre-8.0.tar.gz
[root@varnish-server ~]#cd pcre-8.0/
[root@varnish-server ~]#./configure --prefix=/usr/local/pcre/
[root@varnish-server ~]#make && make install

编译安装varnish

[root@varnish-server ~]#tar -zxvf varnish-2.1.5.tar.gz
[root@varnish-server ~]#cd varnish-2.1.5
[root@varnish-server ~]#export PKG_CONFIG_PATH=/usr/local/pcre/lib/pkgconfig 
[root@varnish-server ~]#./configure --prefix=/usr/local/varnish \
 >--enable-dependency-trackin 
>--enable-debugging-symbols 
>--enable-developer-warnings 
[root@varnish-server ~]#make
[root@varnish-server ~]#make install

其中,“PKG_CONFIG_PATH”是指定varnish查找pcre库的路径,如果pcre安装在了其它路径下,在这里指定相应的路径即可,Varnish默认查找的pcre库路径为/usr/local/lib/ pkgconfig。最后两步操作是拷贝一些varnish守护进程的初始化脚本文件,这些脚本用于varnish的启动、关闭管理等方面,在下面章节中会进行详细讲解。
 至此,varnish安装完毕。


配置说明

1、VCL使用说明
VCL,即为Varnish Configuation Language,用来定义varnish的存取策略,VCL语法比较简单,跟C和perl比较相似,可以使用指定运算符“=”,比较运算符“==”,逻辑运算符“!,&&,!!”等形式。还支持正则表达样和用“~”进行ACL匹配运算,同时还可以使用“set”这样的关键字来指定变量。
需要注意的是,“\”字符在VCL里没有特别的含义,这点与其它语言略有不同,另外,VCL只是配置,并不是真正的编程语言,没有循环,也没有自定义变量。 
在讲述Varnish配置之前,首先需要了解下varnish的配置语法,即VCL,下面对VCL常用的一些内置函数和公用变量进行详细介绍。
VCL内置函数
(1)vcl_recv函数
用于接收和处理请求,当请求到达并成功接收后被调用,通过判断请求的数据来决定如何处理请求。
此函数一般以如下几个关键字结束:
 pass:表示进入pass模式,把请求控制权交给vcl_pass函数。
 pipe:表示进入pipe模式,把请求控制权交给vcl_pipe函数。
 error code [reason]:表示返回“code”给客户端,并放弃处理该请求,“code”是错误标识,例如200、405等,“reason”是错误提示信息。

(2)vcl_pipe函数
此函数在进入pipe模式时被调用,用于将请求直接传递至后端主机,在请求和返回的内容没有改变的情况下,将不变的内容返回给客户端,直到这个链接关闭。
此函数一般以如下几个关键字结束:
 error code [reason] 
 pipe
(3)vcl_pass函数
此函数在进入pass模式时被调用,用于将请求直接传递至后端主机,后端主机应答数据后送给客户端,但不进行任何缓存,在当前连接下每次都返回最新的内容。
此函数一般以如下几个关键字结束:
 error code [reason] 
 pass
(4)lookup
表示在缓存里查找被请求的对象,并且根据查找的结果把控制权交给函数vcl_hit或者函数vcl_miss。
(5)vcl_hit函数
在执行lookup指令后,如果在缓存中找到请求的内容,将自动调用该函数。
此函数一般以如下几个关键字结束:
 deliver:表示将找到的内容发送给客户端,并把控制权交给函数vcl_deliver。
 error code [reason] 
 pass

(6)vcl_miss函数
在执行lookup指令后,如果没有在缓存中找到请求的内容时自动调用该方法,此函数可以用于判断是否需要从后端服务器取内容。
此函数一般以如下几个关键字结束:
 fetch:表示从后端获取请求的内容,并把控制权交给vcl_fetch函数。
 error code [reason] 
 pass
(7)vcl_fetch函数
在从后端主机更新缓存并且获取内容后调用该方法,接着,通过判断获取的内容来决定是否将内容放入缓存,还是直接返回给客户端。
此函数一般以如下几个关键字结束:
 error code [reason]
 pass
 deliver
(8)vcl_deliver函数
在缓存中找到请求的内容后,发送给客户端前调用此方法。此函数一般以如下几个关键字结束:
 error code [reason] 
 deliver

(9)vcl_timeout 函数
此函数在缓存内容到期前调用。一般以如下几个关键字结束:
 discard:表示从缓存中清除该内容。
 fetch
(10)vcl_discard函数
在缓存内容到期后或缓存空间不够时,自动调用该方法,一般以如下几个关键字结束:
 keep:表示将内容继续保留在缓存中。
 discard

2、VCL处理流程图
 通过上面对VCL函数的介绍,读者对各个函数实现的功能已经有了一个了解,其实每个函数之间都是相互关联的,下图列出了varnish处理HTTP请求的一个运行流程图。

处理过程大致分为如下几个步骤:

(1) Receive状态,也就是请求处理的入口状态,根据VCL规则判断该请求应该是Pass或Pipe,或者进入Lookup(本地查询)。
(2) Lookup状态,进入此状态后,会在hash表中查找数据,若找到,则进入Hit状态,否则进入miss状态。
(3) Pass状态,在此状态下,会进入后端请求,即进入fetch状态。 
(4) Fetch状态,在Fetch状态下,对请求进行后端的获取,发送请求,获得数据,并进行本地的存储。
(5) Deliver状态, 将获取到的数据发送给客户端,然后完成本次请求。
3、内置公用变量
 VCL内置的公用变量可以用在不同的VCL函数中,根据这些公用变量使用的不同阶段,下面依次介绍。
当请求到达后,可以使用的公用变量如表2所示:
表2
公用变量名称    含义
req.backend        指定对应的后端主机
server.ip              表示服务器端IP
client.ip               表示客户端IP
req.request          指定请求的类型,例如GET、HEAD、POST等
req.url                 指定请求的地址
req.proto            表示客户端发起请求的HTTP协议版本
req.http.header   表示对应请求中的http头部信息
req. restarts         表示请求重启的次数,默认最大值为4
Varnish               在向后端主机请求时,可以使用的公用变量如表3所示:
表3

公用变量名称 含义
beresp.request 指定请求的类型,例如GET、HEAD等
beresp.url 指定请求的地址
beresp .proto 表示客户端发起请求的HTTP协议版本
beresp .http.header 表示对应请求中的http头部信息
beresp .ttl 表示缓存的生存周期,也就是cache保留多长时间,单位是秒
从cache或者后端主机获取内容后,可以使用的公用变量如表4所示:

表4
公用变量名称 含义
obj.status 表示返回内容的请求状态代码,例如200、302、504等
obj.cacheable 表示返回的内容是否可以缓存,也就是说,如果HTTP返回是200、203、300、301、302、404、410等,并且有非0的生存期,则可以缓存
obj.valid 表示是否是有效的HTTP应答
obj.response 表示返回内容的请求状态信息
obj.proto 表示返回内容的HTTP协议版本
obj.ttl 表示返回内容的生存周期,也就是缓存时间,单位是秒
obj.lastuse 表示返回上一次请求到现在的间隔时间,单位是秒
对客户端应答时,可以使用的公用变量如表5所示:

表5
公用变量名称 含义
resp.status 表示返回给客户端的HTTP状态代码
resp.proto 表示返回给客户端的HTTP协议版本
resp.http.header 表示返回给客户端的HTTP头部信息
resp.response 表示返回给客户端的HTTP状态信息
在上面的讲述中,我们只是介绍了常用的VCL内置公用变量,如果需要了解和使用更多的公用变量信息,请登录varnish官方网站查阅。

三 、配置一个简单的Varnish实例
 由于版本的不同,Varnish配置文件的写法也存在一定差异,varnish2.x版本和1.x版本之间不但配置文件写法不同,而且新的版本功能也增加很多,并且去除了很多应用BUG,这里讲述的版本是varnish2.1.2,配置文件写法也以varnish2.x版本为基准。
Varnish安装完成后,默认的配置文件为/usr/local/varnish/etc/varnish/default.vcl,此文件内容默认全部被注释掉了,这里,我们以这个文件为模板,创建一个新的文件vcl.conf,并且放到/usr/local/varnish/etc目录下,配置完成的vcl.conf文件如下:
#通过backend定义了一个名称为webserver的后端主机,“.host”指定后端主机的IP地址或者域名,“.port”指定后端主机的服务端口

backend webserver {
     .host = "127.0.0.1";
     .port = "80";
 }

#调用vcl_recv开始。
sub vcl_recv {
        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;
        }
#如果请求的类型不是GET、HEAD、PUT、POST、TRACE、OPTIONS、DELETE时,进入pipe模式。注意这里是“&&”的关系。
        if (req.request != "GET" &&
           req.request != "HEAD" &&
           req.request != "PUT" &&
           req.request != "POST" &&
           req.request != "TRACE" &&
           req.request != "OPTIONS" &&
           req.request != "DELETE") {
           return (pipe);

        }
#如果请求的类型不是GET与HEAD,则进入pass模式。
   if (req.request != "GET" && req.request != "HEAD") {
           return (pass);
        }

#对ixdba.net或者ixdba.cn两个域名进行缓存加速,这是个泛域名的概念,也就是所有以ixdba.net或者ixdba.cn结尾的域名都进行缓存。
        if (req.http.host ~ "^(.*).ixdba.net" || req.http.host ~ "^(.*).ixdba.cn") {
           set req.backend = webserver;
        }

#对以.jsp和.do结尾以及带有?的URL时,直接从后端服务器读取内容。
        if (req.url ~ "\.(jsp|do)($|\?)") {
           return (pass);
        } else {
        return (lookup);
        }
}
 
sub vcl_pipe {
    return (pipe);
}

sub vcl_pass {
    return (pass);
}
 
sub vcl_hash {
    set req.hash += req.url;
    if (req.http.host) {
        set req.hash += req.http.host;
    } else {
        set req.hash += server.ip;
    }
    return (hash);
}
 
sub vcl_hit {
    if (!obj.cacheable) {
        return (pass);
    }
    return (deliver);
}

sub vcl_miss {
    return (fetch);
}
 
sub vcl_fetch {
     if (!beresp.cacheable) {
         return (pass);
     }
     if (beresp.http.Set-Cookie) {
         return (pass);
     }

#当url中包含servlet时,不进行缓存。
    if (req.url ~ "^/servlet/") {
        return (pass);
    }

#对于请求类型是GET,并且请求的URL中包含upload,那么就进行缓存,缓存的时间是300秒,即5分钟。
    if (req.request == "GET" && req.url ~ "^/upload(.*)$") {
       set beresp.ttl = 300s;
    }

#对于请求类型是GET,并且请求的URL以png、xsl、xml、gif、css、js等结尾时,则进行缓存,缓存时间为600秒。
    if (req.request == "GET" && req.url ~ "\.(png|xsl|xml|pdf|ppt|doc|docx|chm|rar|zip|bmp|jpeg|swf|ico|mp3|mp4|rmvb|ogg|mov|avi|wmv|swf|txt|png|gif|jpg|css|js|html|htm)$") {
       set beresp.ttl = 600s;
    }
    return (deliver);
}

启动varnish服务:

启动参数说明
-a address:port # varnishd httpd监听地址及其端口
-b address:port # 后台服务器地址及其端口
# -b
# -b ‘:’
-d # 使用debug模式
-f file # varnishd 服务器存取规则文件
-F # Run in foreground
-h kind[,hashoptions] # Hash specification
# -h simple_list
# -h classic [default]
# -h classic,
-n dir # varnishd working directory
-P file # PID file
-p param=value # 服务器参数,用来优化性能
-s kind[,storageoptions] # 缓存内容存放方式
# -s malloc
# -s file [default: use /tmp]
# -s file,
# -s file,,
-t # Default TTL
-T address:port # telnet管理地址及其端口
-V # version
-w int[,int[,int]] # 工作线程数
# -w
# -w min,max
# -w min,max,timeout [default: -w1,1000,120]

./varnishd -a 10.127.64.223:8080 -T 10.127.64.223:8081 -f /usr/local/varnish/etc/vcl.conf 

varnish状态查看:

Varnish提供了一个varnishstat命令,通过它可以获得很多重要的信息。

####################

0+00:48:33                                                                                                              WEB_YQ_64.223

Hitrate ratio:        1        1        1

Hitrate avg:     0.7333   0.7333   0.7333


          12         0.00         0.00 Client connections accepted

          45         0.00         0.02 Client requests received

          33         0.00         0.01 Cache hits

          12         0.00         0.00 Cache misses

           4         0.00         0.00 Backend conn. success

           8         0.00         0.00 Backend conn. reuses

           3         0.00         0.00 Backend conn. was closed

          12         0.00         0.00 Backend conn. recycles

           7         0.00         0.00 Fetch with Length

           5         0.00         0.00 Fetch chunked

          10          .            .   N struct sess_mem

           2          .            .   N struct objectcore

           2          .            .   N struct objecthead

           1          .            .   N struct smf

           1          .            .   N large free smf

           1          .            .   N struct vbe_conn

          10          .            .   N worker threads

          10         0.00         0.00 N worker threads created

           1          .            .   N backends

          10          .            .   N expired objects

          11          .            .   N LRU moved objects

          39         0.00         0.01 Objects sent with write

          12         0.00         0.00 Total Sessions

          45         0.00         0.02 Total Requests

          12         0.00         0.00 Total fetch

        9397         0.00         3.23 Total header bytes

      336431         0.00       115.49 Total body bytes

          45         0.00         0.02 Session Linger

          42         0.00         0.01 Session herd

##################

这里需要注意以下几点:

“Client connections accepted”表示客户端向反向代理服务器成功发送HTTP请求的总数量。

“Client requests received”表示到现在为止,浏览器向反向代理服务器发送HTTP请求的累计次数。由于可能会使用长连接,因此这个值一般会大于“Client connections accepted”的值。

“Cache hits”表示反向代理服务器在缓存区中查找并且命中缓存的次数。

“Cache misses”表示直接访问后端主机的请求数量,也就是非命中数。

“N struct object”表示当前被缓存的数量。

“N expired objects”表示过期的缓存内容数量。

“N LRU moved objects”表示被淘汰的缓存内容个数。