一、安装准备工作
1.建立varnish用户以及用户组,并且创建Varnish缓存目录和日志目录:
useradd    -s /sbin/nologin varnish
mkdir /data/varnish/cache
mkdir /data/varnish/log
chown -R varnish:varnish    /data/varnish/cache
chown -R varnish:varnish    /data/varnish/log

2.安装pcre,ncurses-devel
 
cd ./pcre-8.20

./configure --prefix=/usr/local/pcre

     make && make install

    yum install ncurses-devel

3.安装varnish
cd varnish-3.0.0
export PKG_CONFIG_PATH=/usr/local/pcre/lib/pkgconfig
其中,“PKG_CONFIG_PATH”是指定varnish查找pcre库的路径,如果pcre安装在了其它路径下,在这里指定相应的路径即可,Varnish默认查找的pcre库路径为/usr/local/lib/ pkgconfig
./configure --prefix=/usr/local/varnish --enable-dependency-tracking --enable-debugging-symbols --enable-developer-warnings
make
make install

配置varnish配置文件,如下是我的范例
##############通过backend定义后端主机##############
backend wiki {
             .host = "192.168.137.111";
             .port = "80";
             .connect_timeout = 1s;
             .first_byte_timeout = 5s;
             .between_bytes_timeout = 2s;

}

backend server82 {
             .host = "192.168.137.111";
             .port = "82";
}

backend server83 {
             .host = "192.168.137.111";
             .port = "83";
}

backend server84 {
             .host = "192.168.137.111";
             .port = "84";
}


###############定义一个名字为server的director
director server random {
  {.backend = server82; .weight=5;}
  {.backend = server83; .weight=5;}
  {.backend = server84; .weight=5;}
}

###############设置清理缓存规则varnish允许那些IP通过PURGE方法清除缓存
acl purge {
                "localhost";
                "127.0.0.1";
  "192.168.137.0"/26;
}

#################非允许IP发送PURGE清理缓存时将返回405状态
sub vcl_recv {
                if (req.request == "PURGE") {
                                if (!client.ip ~ purge) {
                                                error 405 "Not allowed.";
      return(lookup);
                                }
                }

                if (req.http.host ~ "^wiki.wangqiao.cn") {
                                set req.backend = wiki;
                }
  else
                if(req.http.host ~ "^server.wangqiao.cn") {
    set req.backend = server;
  }
  else
  if(req.http.host ~ "^(.*).wangqiao.cn" || req.http.host ~ "^(.*).wangqiao.com") {
                                set req.backend = server;
                }
  else
  {
                                error 404 "Wang Qiao Cache Server";
                }

###########清除url中有jpg|png|gif等文件的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;
  }
####################如果请求的类型不是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);
                     }    
########请求以.cgi和.php结尾带有?的url时不进行缓存直接从后端服务器读取内容                    
                     if (req.http.Authorization || req.http.Cookie) {
                            return (pass);
                     }
                    
                     if (req.request == "GET" && req.url ~ "\.(cgi|php)($|\?)") {
                             return (pass);
                            }
                         return (lookup);

}



sub vcl_pipe {
                return (pipe);
}
sub vcl_pass {
             return (pass);
}
#######如果请求的类型是PURGE方法,varnish会将此请求的缓存周期设置为0,也就是使这个url的缓存失败从而刷新varnish缓存的目的
sub vcl_hit {
                if (req.request == "PURGE") {
                                set obj.ttl = 0s;
                                error 200 "Purged.";
                }
}
sub vcl_miss {
  return (fetch);
}

###############定义不同的缓存时间###

sub vcl_fetch {
  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)$")
  {
    set beresp.ttl = 1d;
  }

                if (req.request == "GET" && req.url ~ "\.(html|htm)$") {
                                set beresp.ttl = 1d;
                }


  if (req.request == "GET" && req.url ~ "^/upload(.*)$") {
    set beresp.ttl = 300s;
  }
#################当url中包含server时不进行缓存
                if (req.url ~ "^/services/") {
    return (deliver);
  }
##########定义在什么状态下进入restart模式  
  if (beresp.status == 500 || beresp.status == 501 || beresp.status == 502 || beresp.status == 503 || beresp.status == 504 || beresp.status == 404) {
    return (restart);
  }
###########定义不缓存含有那些HTTP头请求
  if (beresp.http.Pragma ~ "no-cache" ||
    beresp.http.Cache-Control ~ "no-cache" ||
    beresp.http.Cache-Control ~ "private") {
    return (deliver);
  }
}

###########添加一个header标识,以判断缓存是否命中
sub vcl_deliver {
    set resp.http.x-hits = obj.hits;
    if (obj.hits > 0) {
     set resp.http.X-Cache = "HIT form wangqiao";
    } else {
     set resp.http.X-Cache = "MISS from wangqiao";
  }
    return(deliver);
}

##############定义hash值并处理压缩内容
sub vcl_hash {
         hash_data(req.url);
         if (req.http.host) {
                 hash_data(req.http.host);
         } else {
                 hash_data(server.ip);
         }

         if (req.http.Accept-Encoding) {
                                if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
                                remove req.http.Accept-Encoding;
                                remove req.http.Cookie;
                                } else if (req.http.Accept-Encoding ~ "gzip") {
                                                set req.http.Accept-Encoding = "gzip"; }
                                else if (req.http.Accept-Encoding ~ "deflate") {
                                                set req.http.Accept-Encoding = "deflate";
                                }
                                else {
                                                remove req.http.Accept-Encoding;
                                                }
                                }

         return (hash);
}


VCL内置函数
1vcl_recv函数
 用于接收和处理请求,当请求到达并成功接收后被调用,通过判断请求的数据来决定如何处理请求。
 此函数一般以如下几个关键字结束:
q pass:表示进入pass模式,把请求控制权交给vcl_pass函数。
q pipe:表示进入pipe模式,把请求控制权交给vcl_pipe函数。
q error code [reason]:表示返回“code”给客户端,并放弃处理该请求,“code”是错误标识,例如200405等,“reason”是错误提示信息。
 (2vcl_pipe函数
 此函数在进入pipe模式时被调用,用于将请求直接传递至后端主机,在请求和返回的内容没有改变的情况下,将不变的内容返回给客户端,直到这个链接关闭。
 此函数一般以如下几个关键字结束:
q error code [reason]
q pipe
3vcl_pass函数
 此函数在进入pass模式时被调用,用于将请求直接传递至后端主机,后端主机应答数据后送给客户端,但不进行任何缓存,在当前连接下每次都返回最新的内容。
 此函数一般以如下几个关键字结束:
q error code [reason]
q pass
4lookup
表示在缓存里查找被请求的对象,并且根据查找的结果把控制权交给函数vcl_hit或者函数vcl_miss
 (5vcl_hit函数
 在执行lookup指令后,如果在缓存中找到请求的内容,将自动调用该函数。
 此函数一般以如下几个关键字结束:
q deliver:表示将找到的内容发送给客户端,并把控制权交给函数vcl_deliver
q error code [reason]
q pass
6vcl_miss函数
 在执行lookup指令后,如果没有在缓存中找到请求的内容时自动调用该方法,此函数可以用于判断是否需要从后端服务器取内容。
 此函数一般以如下几个关键字结束:
q fetch:表示从后端获取请求的内容,并把控制权交给vcl_fetch函数。
q error code [reason]
q pass
7vcl_fetch函数
 在从后端主机更新缓存并且获取内容后调用该方法,接着,通过判断获取的内容来决定是否将内容放入缓存,还是直接返回给客户端。
 此函数一般以如下几个关键字结束:
q error code [reason]
q pass
q deliver
8vcl_deliver函数
 在缓存中找到请求的内容后,发送给客户端前调用此方法。此函数一般以如下几个关键字结束:
q error code [reason]
q deliver
9vcl_timeout 函数
 此函数在缓存内容到期前调用。一般以如下几个关键字结束:
q discard:表示从缓存中清除该内容。
q fetch
10vcl_discard函数
 在缓存内容到期后或缓存空间不够时,自动调用该方法,一般以如下几个关键字结束:
q keep:表示将内容继续保留在缓存中。
q discard

4.启动varnish
/usr/local/varnish/sbin/varnishd -n /data/varnish/cache -u varnish -g varnish -f /usr/local/varnish/vcl.conf -a 0.0.0.0:80 -s file,/data/varnish/cache/vcache_cache.data,50M -w 10,51200,10 -t 3600 -T 127.0.0.1:3500 -P /var/run/varnishd.pid
命令参数 参数含义  
-a address:port 表示varnishhttpd的监听地址及其端口  
-b address:port 表示后端服务器地址及其端口  
-d 表示使用debug调试模式  
-f file 指定varnish服务器的配置文件  
-p param=value 指定服务器参数,用来优化varnish性能  
-P file Varnish进程PID文件存放路径  
-n dir 指定varnish的工作目录  
-s kind[,storageoptions] 指定varnish缓存内容的存放方式,常用的方式有:“-s file,<dir_or_file>,<size>”。  
10 其中“<dir_or_file>”指定缓存文件的存放路径,“<size>”指定缓存文件的大小  
11 -t 指定缺省的TTL值  
12 -T address:port 设定varnishtelnet管理地址及其端口  
13 -w int[,int[,int]] 设定varnish的工作线程数,常用的方式有:  
14 -w min,max  
15 -w min,max,timeout  
16 例如:-w5,51200,30,这里需要说明下,在varnish2.0版本以后,最小启动的线程数不能设定过大,设置过大,会导致varnish运行异常缓慢。
17  -V 显示varnish版本号和版权信息

varnish得到日常维护

访问日志写入文件
 /usr/local/varnish/bin/varnishncsa -n /data/varnish/cache -w /var/log/varnish.log &

获得Varnish详细的系统运行日志
/usr/local/varnish/bin/varnishlog -n  /data/varnish/cache| grep CLI

清除缓存
/usr/local/varnish/bin/varnishadm -T 127.0.0.1:3500 ban.url index.html

列出最近清除的详细URL列表
/usr/local/varnish/bin/varnishadm -T 127.0.0.1:3500 ban.list

通过查看网页头来查看命中情况
查看Varnish服务器连接数与命中率
/usr/local/varnish/bin/varnishstat -n /data/varnish/cache

其中几个比较重要的选是
cache-hit :代表缓存命中次数
miss-hit   :代表未命中次数
worker threads :代表当前工作线程的数量
expired objects :代表过期对象的个数
LRU nuked objects :代表缓存可使用的内存以达上线而不得不移除的对象个数
LRU moved objects :代表LRU策略被移动的对象个数
Total header bytes :代表缓存的请求头对象的大小
Total body bytes :代表缓存的请求体对象大小

如果有不对的地方,请各位大神指出,小弟不甚感激!