varnish的资料相信大家也看过很多,在这里我也不对此做过多的说明,只要大家都知道,varnish是很好的缓存服务器即可,以下是相关安装及配置方法

h1. Varnish安装指南

h2. 手动安装

* 下载varnish-3.0.2安装包,地址:http://repo.varnish-cache.org/source/varnish-3.0.2.tar.gz

wget -S http://repo.varnish-cache.org/source/varnish-3.0.2.tar.gz

* 解压varnish安装包

tar zxf varnish-3.0.2.tar.gz

* 进入varnish-3.0.2目录,执行命令:

./autogen.sh
./configure –prefix=/usr/local/varnish –enable-dependency-trackin –enable-debugging-symbols –enable-developer-warnings
make && make install

varnish No package 'libpcre' found 
说是缺少 pcre。我安装nginx的时候用到了pcre 安装了的
使用以下办法
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig


* 修改varnish配置文件/usr/local/varnish/etc/varnish/default.vcl,示例配置文件如下:

 # Default backend definition.  Set this to point to your content server.
 backend default {
     .host = "127.0.0.1";
     .port = "8080";
 }

 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);
 }

 sub vcl_pipe {
     return (pipe);
 }

 sub vcl_pass {
     return (pass);
 }

 sub vcl_hash {
     hash_data(req.url);
     if (req.http.host) {
         hash_data(req.http.host);
     } else {
         hash_data(server.ip);
     }
     return (hash);
 }

* 新增加一个启动文件/etc/init.d/varnish,内容如下:

#!/bin/sh
#
# Init file for varnish server daemon
#
# chkconfig: 2345 55 25
# description: varnish server daemon
#
# processname: varnish
#

workdir=/usr/local/varnish
name=varnish
command=${workdir}/sbin/varnishd
conf=${workdir}/etc/varnish/default.vcl
PID=/var/run/varnish.pid

wait_for_pid () {
    try=0

    while test $try -lt 5 ; do

        case "$1" in
            'created')
            if [ -f "$2" ] ; then
                try=''
                break
            fi
            ;;

            'removed')
            if [ ! -f "$2" ] ; then
                try=''
                break
            fi
            ;;
        esac

        echo -n .
        try=`expr $try + 1`
        sleep 1

    done

}

case "$1" in
    start)
        echo -n "Starting $name " 
        ulimit -n 65001
        $command -f $conf -s malloc,1G -T 127.0.0.1:2000 -a 0.0.0.0:80

        if [ "$?" != 0 ] ; then
            echo " failed" 
            exit 1
        fi

        wait_for_pid created $PID

        if [ -n "$try" ] ; then
            echo " failed" 
            exit 1
        else
            echo " done" 
        fi
    ;;

    stop)
        echo -n "Gracefully shutting down $name " 

        if [ ! -r $PID ] ; then
            echo "warning, no pid file found - $name is not running ?" 
            exit 1
        fi

        kill -TERM `cat $PID`

        wait_for_pid removed $PID

        if [ -n "$try" ] ; then
            echo " failed. Use force-exit" 
            exit 1
        else
            echo " done" 
        fi
    ;;

    force-quit)
        echo -n "Terminating $name " 

        if [ ! -r $PID ] ; then
            echo "warning, no pid file found - $name is not running ?" 
            exit 1
        fi

        kill -TERM `cat $PID`

        wait_for_pid removed $PID

        if [ -n "$try" ] ; then
            echo " failed" 
            exit 1
        else
            echo " done" 
        fi
    ;;

    test)
       echo "Test $name configure" 
       $command -t $config
       if test $? -ne 0; then
          exit 1
       fi
    ;;

    restart)
        $0 test
        $0 stop
        $0 start
    ;;

    reload)

        echo -n "Reload service $name " 

        echo " not supported" 
    ;;

    *)
        echo "Usage: $0 {start|stop|force-quit|restart|reload|test}" 
        exit 1
    ;;

esac

* 将脚本varnish加入自动化启动,执行如下命令:

chkconfig --add varnish&& chkconfig --level 135 varnish on

也可使用以下开机启动方式
配置开机自动启动Varnish
vim /etc/rc.d/rc.local
在末行写入以下内容:
ulimit -SHn 65535
/usr/local/varnish/sbin/varnishd -u www -g www -f /usr/local/varnish/etc/varnish/varnish.conf -a 0.0.0.0:80 -s file,/data1/varnish_cache/varnish_cache.data,100M -w 1024,8192,10 -t 3600 -T 127.0.0.1:3500
/usr/local/varnish/bin/varnishncsa -w /data/logs/varnish.log &

通过Varnish管理端口,使用正则表达式批量清除缓存
清除所有缓存
/usr/local/varnish-2.1.3/bin/varnishadm -T 127.0.0.1:3500 url.purge *$
清除image目录下所有缓存
/usr/local/varnish-2.1.3/bin/varnishadm -T 127.0.0.1:3500 url.purge /image/
127.0.0.1:3500 为被清除缓存服务器地址 www.kangta.com 为被清除的域名 /static/image/tt.jsp 为被清除的url地址列表
/usr/local/varnish-2.1.3/bin/varnishadm -T 127.0.0.1:3500 purge “req.http.host ~ www.funshion.com$ && req.url ~ /static/image/tt.jsp”

查看Varnish服务器连接数与命中率:
/usr/local/varnish/bin/varnishstat

以上为varnish的状态,
1675 0.00 0.06 Client requests received 为服务端接收的客户端请求次数
179 0.00 0.01 Cache hits 为命中缓存,从缓存中取得数据返回给客户端的次数,即命中率
11 0.00 0.00 Cache misses 为跳过pass缓存,从后端服务应用中取得数据返回给用户的次数

用help看看可以使用哪些Varnish命令:
/usr/local/varnish/bin/varnishadm -T 127.0.0.1:3500 help

400错误出现,是因为varnish认为客户端请求header行数及长度过大,其默认最大接受的请求header行数为64,最大长度(所有请求header行长度之和)为2048,解决这个问题比较简单,在varnish启动参数中加入:
-p http_max_hdr=256
-p http_req_hdr_len=8192

* 以下是一份完整的配置说明,不明白各项参数的可以参考下,以下资源来源于网络整理

#http请求处理过程
#1,receive请求入口状态,根据vcl判断pass还是lookup本地查询
#lookup,在hash表中查找数据,若找到则进入hit状态,否则进入fetch状态
#pass,选择后台,进入fetch状态
#fetch,对请求进行后端的获取,发送请求,获得数据,并进行本地存储
#deliver,将数据发送给客户端,进入done
#done,处理结束

##########配置后端服务器##############
backend kangta01 {
.host = “192.168.1.142”;
.port = “7070”;
.probe = {
.timeout = 5s;
.interval = 2s;
.window = 10;
.threshold = 8;
}
}
backend kangta02 {
.host = “192.168.1.141”;
.port = “7070”;
.probe = {
.timeout = 5s;
.interval = 2s;
.window = 10;
.threshold = 8;
}
}
##############配置后端服务器组,进行健康检测6秒,使用random方式设置权重########
#########另一种方式round-robin则默认轮询机制####################
director kangta15474 random
{ .retries = 6;
{ .backend = kangta02;
.weight = 2;
}
{ .backend = kangta01;
.weight = 2;
}
}
##########定义访问列表,允许下列地址清除varnish缓存#######################
acl local {
“localhost”;
“127.0.0.1”;
}

########从url判断针对哪类后面服务器及缓存配置############################

sub vcl_recv
{
if (req.http.host ~ “^kangta15474.vicp.net”) #匹配域名跳转后台服务器
{ set req.backend = kangta15474; }
else { error 404 “Unknown HostName!”; }
if (req.request == “PURGE”) #不允许非访问控制列表内的IP清除varnish缓存
{ if (!client.ip ~ local)
{
error 405 “Not Allowed.”;
return (lookup);
}
}
#清除url中有jpg等文件的cookie
if (req.request == “GET” && req.url ~ “\.(jpg|png|gif|swf|jpeg|ico)$”)
{
unset req.http.cookie;
}
#判断req.http.X-Forwarded-For 如果前端有多重反向代理,这样可以获取客户端IP地址。
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; }
##varnish实现图片的防盗链
# if (req.http.referer ~ “http://.*)
# {
# if ( !(req.http.referer ~ “http://.*vicp\.net” ||
# req.http.referer ~ “http://.*kangta15474\.net” ) )
# {
# set req.http.host = “kangta15474.vicp.net”;
# set req.url = “/referer.jpg”;
# }
# return(lookup);
# }
# else {return(pass);}
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请求的直接转发给后端服务器
if (req.request != “GET” && req.request != “HEAD”)
{ return (pass); }
##对GET请求,且url里以.php和.php?结尾的,直接转发给后端服务器
if (req.request == “GET” && req.url ~ “\.(php)($|\?)”)
{ return (pass); }
##对请求中有验证及cookie,直接转发给后端服务器
if (req.http.Authorization || req.http.Cookie)
{ return (pass);}
{
##除以上的访问请求,从缓存中查找
return (lookup);
}
##指定的font目录不进行缓存
if (req.url ~ “^/fonts/”)
{ return (pass); }
}

sub vcl_pipe
{ return (pipe); }
##进入pass模式,请求被送往后端,后端返回数据给客户端,但不进入缓存处理
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);
}
##在lookup后如果在cache中找到请求的缓存,一般以下面几个关键词结束
sub vcl_hit
{
if (!obj.cacheable)
{ return (pass); }
return (deliver);
}
##lookup后没有找到缓存时调用,以下面几个关键词结束,及调用fetch参数重新测试是否加入缓存
sub vcl_miss
{ return (fetch); }

#让varnish服务器缓存的类型,从后端取得数据后调用
sub vcl_fetch
{ if (!beresp.cacheable)
{ return (pass); }
if (beresp.http.Set-Cookie)
{ return (pass); }
##WEB服务器指明不缓存的内容,varnish服务器不缓存
if (beresp.http.Pragma ~ “no-cache” || beresp.http.Cache-Control ~ “no-cache” || beresp.http.Cache-Control ~ “private”)
{ return (pass); }
##对访问中get有包含jpg,png等格式的文件进行缓存,缓存时间为7天,s为秒
if (req.request == “GET” && req.url ~ “\.(js|css|mp3|jpg|png|gif|swf|jpeg|ico)$”)
{ set beresp.ttl = 7d; }
##对访问get中包含htm等静态页面,缓存300秒
if (req.request == “GET” && req.url ~ “\/[0-9]\.htm$”)
{ set beresp.ttl = 300s; }
return (deliver);
}
####添加在页面head头信息中查看缓存命中情况########
sub vcl_deliver
{
set resp.http.x-hits = obj.hits ;
if (obj.hits > 0)
{ set resp.http.X-Cache = “HIT cqtel-bbs”; }
else { set resp.http.X-Cache = “MISS cqtel-bbs”; }
}

Subroutine列表
vcl_recv
在请求开始时候被调用,在请求已经被接收到并且解析后调用目的就是决定是否处理这个请求,怎么处理,使用哪个后端vcl_recv以return结束,参数可以为如下关键字:
error code [reason]:返回错误码给客户端,丢弃请求
pass:转换到pass模式控制权最后会转移到vcl_pass
pipe:转换到pipe模式控制权最后会转移到vcl_pipe
lookup:在缓存中寻找请求对象控制权最后会转移到vcl_hit或者vcl_miss,决定于对象是否在缓存中
vcl_pipe
当进入pipe模式的时候被调用在这个模式中,请求会被转移到后端,后续的数据不管是从客户端还是后端来的都会以不变的方式传送,直到连接关闭为止vcl_pipe以return结束,参数可以为如下关键字:
error code [reason]:返回错误码给客户端,丢弃请求
pipe:以pipe模式执行
vcl_pass
当进入pass模式的时候会被调用在这个模式中,请求会被传送到后端,然后后端的响应会被传送回客户端,但是响应不会进入缓存中接下来通过相同客户端连接发起的请求会以普通的方式来处理vcl_pass以return结束,参数可以为如下关键字:
error code [reason]:返回错误码给客户端,丢弃请求
pass:以pass模式执行
restart:重新启动这个事务增加了重启计数如果重启的次数高于max_restarts,varnish会引起一个错误
vcl_hash
你如果把想把数据加入到hash中,那么调用hash_data()vcl_hash以return结束,参数可以为如下关键字:
hash:执行hash逻辑
vcl_hit
如果请求的对象在缓存中被找到了,那么在缓存查找结束后被调用vcl_hit以return结束,参数可以为如下关键字:
deliver:deliver缓存对象到客户端控制权最后会转移到vcl_deliver
error code [reason]:返回错误码给客户端,丢弃请求
pass:切换到pass模式控制权最后会转移到vcl_pass
restart:重新启动这个事务增加了重启计数如果重启的次数高于max_restarts,varnish会引起一个错误
vcl_miss
如果请求的对象在缓存中没有被找到,那么在缓存查找结束后被调用目的是为了决定是否去后端获取这个请求对象,并且要选择哪个后端vcl_miss以return结束,参数可以为如下关键字:
error code [reason]:返回错误码给客户端,丢弃请求
pass:切换到pass模式控制权最后会转移到vcl_pass
fetch:去后端获取请求对象控制权最后会转移到vcl_fetch
vcl_fetch
当一个对象被成功从后端获取的时候此方法会被调用vcl_fetch以return结束,参数可以为如下关键字:
deliver:可能把对象放入缓存中,然后再deliver到客户端控制权最后会转移到vcl_deliver
error code [reason]:返回错误码给客户端,丢弃请求
esi:以ESI形式来处理刚刚被获取到的对象
pass:切换到pass模式控制权最后会转移到vcl_pass
restart:重新启动这个事务增加了重启计数如果重启的次数高于max_restarts,varnish会引起一个错误
vcl_deliver
当一个缓存的对象被deliver到客户端的时候,此方法会被调用vcl_deliver以return结束,参数可以为如下关键字:
deliver:发送对象到客户端
error code [reason]:返回错误码给客户端,丢弃请求
restart:重新启动这个事务,增加重启计数如果重启的次数高于max_restarts,varnish会引起一个错误
vcl_error
当遇见一个错误的时候会被调用,错误可能是跟后端有关系或者内部错误vcl_error以return结束,参数可以为如下关键字:
deliver:发送对象到客户端
restart:重新启动这个事务,增加重启计数如果重启的次数高于max_restarts,varnish会引起一个错误

重要变量

subroutine不带参数,一般通过全局变量来实现信息的传递

如下变量在backend中有效:
.host:backend的主机名或者IP
.port:backend的端口

如下变量在处理一个请求(例如vcl_recv)的时候可用:
client.ip:客户端IP地址
server.hostname:服务器的主机名
server.identity:服务器标示,当启动varnish的时候用”-i”参数来指定如果varnish启动时候没有指定”-i”参数,那么server.identity会被设置为用”-n”参数所指定的实例名称
server.ip:服务器IP地址
server.port:服务器端口
req.request:请求类型(例如“GET”,“HEAD”)
req.url:请求的URL
req.proto:HTTP协议版本
req.backend:处理请求的后端服务器
req.backend.healthy:后端是否健康health check需要在backend的probe中进行设置
req.http.header:相关的HTTP头
req.hash_always_miss:强迫对于本次请求的缓存查找结果为miss如果设置为”true”,那么varnish将会忽略任何存在的缓存对象,一直从后端重新获取资源
req.hash_ignore_busy:在缓存查找时候忽略任何忙的对象如果有两个服务器,彼此互相查找缓存内容,那么可以使用这个变量来避免潜在的死锁

如下变量在准备一个后端请求(比如在cache miss或者pass,pipe模式)的时候可用:
bereq.request:请求的类型(比如“GET”,“HEAD”)
bereq.url:请求的URL
bereq.proto:与后端服务器交互的HTTP协议版本
bereq.http.header:相关的HTTP头
bereq.connect_timeout:与后端连接的超时时间
bereq.first_byte_timeout:从后端返回第一个字节所需等待的秒数,在pipe模式中不可用
bereq.between_bytes_timeout:从后端返回的每个字节之间的时间间隔,以秒计在pipe模式中不可用

如下的变量在请求对象从后端返回之后,在其被放入缓存之前可用换句话说,也就是在vcl_fetch中可用
beresp.proto:HTTP协议版本
beresp.status:后端返回的HTTP状态码(例如200,302等)
beresp.response:后端返回的状态内容(例如“OK”,“Found”)
beresp.cacheable:如果请求的结果是可以被缓存的,那么此变量为”true”如果HTTP状态码为200, 203, 300, 301, 302, 404,410之一并且pass没有在vcl_recv中被调用,那么这个结果就是可以被缓存的如果response的TTL和grace time都为0,那么beresp.cacheable将会为0beresp.cacheable是可写的
beresp.ttl:缓存对象的生存时间,以秒为单位,这个变量是可写的

在对象已经存在于缓存中并被查询到的时候,一般在vcl_hit和vcl_deliver中,如下的变量(大部分是read-only)可用:
obj.proto:与后端交互的HTTP版本协议
obj.status:后端返回的HTTP状态码
obj.response:后端返回的HTTP状态内容
obj.cacheable:如果对象的beresp.cacheable为”true”,那么此变量的值为”true”除非你强制delivery,否则obj.cacheable一直为”true”
obj.ttl:缓存对象的生存时间,以秒为单位,这个变量是可写的
obj.lastuse:从现在到对象最近一次访问所间隔的时间,以秒为单位
obj.hits:对象被发送到客户端的次数,0表示缓存查询miss了

如下变量在决定对象hash key的时候可用:
req.hash:hash key被用来关联一个缓存中的对象在读写缓存的时候都会被用到

如下变量在准备把一个响应发送给客户端时候可用:
resp.proto:响应使用的HTTP协议版本
resp.status:将要返回的HTTP状态码
resp.response:将要返回的HTTP状态内容
resp.http.header:相关的HTTP头



分享到: 更多

这篇日志的 QR 二维码为:

四月 19th, 2012

Posted In: linux系统

标签:, ,

发表评论

电子邮件地址不会被公开。 必填项已用*标注

无觅相关文章插件,快速提升流量