首页 > 代码库 > varnish基础应用

varnish基础应用

varnish基础应用

1.程序的运行具有局部性特征

    在时间上有局部性:访问某数据之后缓存下来,将来可能还会访问
    在空间性有局部性:一个空间内的数据被访问了,紧挨着的数据也有可能会访问,将会被缓存下来
2.热区表现于数据的局部性,例:20%的数据支撑80%销量

3.数据具有热点:经常被访问的数据就是热点
4.缓存项命中率:判断缓存的利用率的衡量指标,hit/(hit+miss),小于1大于0 的开区间表示:
   文档命中率:也叫资源命中率;从缓存中命中文档页面的个数进行衡量;
   字节命中率:文档命中次数有可能不高,但文件是大文件;从命中的内容大小进行衡量,例:100个文件,一共100M,从缓存中命中10个文件,占用50M空间,此空间就是字节命中率
5.缓存的生命周期:
  缓存清理:有两种场景:
   1.缓存项过期:
   
2.缓存空间用尽:LRU算法(最近最少使用)
例如,dns服务的解析结果也可缓存,而缓存多长时间是在dns服务器上每一条资源记录上ttl定义的;

 

6.缓存标准:
   私有数据:不可缓存,只能用户自己缓存;
   公共数据:公开地,都可以缓存


缓存控制机制:
一、缓存过期日期:

  1、HTTP/1.0 Expires(http首部) :定义的缓存过期为绝对时间
例如:Expires:Fri,20 May 2016 02:03:18 GMT     
//绝对时间,表示在某一时间点缓存过期,有局限性,如果时区不同,会有影响;这种控制机制有缺陷;

2、HTTP/1.1 Cache-Control:max-age  :定义的缓存过期的相对时间
例如:Cache-Control:on-transform,max-age=3600----在缓存生成之后多少时间后失效----是相对时长控制机制;

二、Cache-Control:缓存控制首部,请求响应报文都可以使用

    1、cache-request-directive  =   VALUE  ----请求首部报文缓存,主要目的是,告诉缓存服务器只接收哪些类型的资源;
    2、cache-extension   //缓存扩展
    3、cache-reponse-directive //响应首部报文缓存
    4、public   //只能响应报文中,可以被任何缓存进行缓存

  5、private  //只能存放私有缓存

     6、no-cache   //对于响应者告诉客户端no-cache,表示能缓存,但客户端下次请求时,即便命中也不能使用缓冲内容响应客户端,必须要到原始服务器查询验证缓存是否过期;
     7、no-stroe   //对于请求报文时,服务器不能检测缓存,必须通过服务器响应真实数据,不能缓存,内容不允许被缓存;
    8、must-revalidate  //必须做重新校验;内容缓存后,即便命中时必须到后端服务器进行验证,跟no-cahce相似;
     9、max-age   //定义相对时间的可以缓存有效时间,是相对时长,用在客户端重复请求同一资源时未避免重复向服务器请求验证缓存项是否过期时使用,定义此时间可让客户端在指定时间内不向服务器请求验证缓存项是否过期
    10、s-maxage   //定义公共缓存服务器可缓存时长;

响应报文指明的缓存时长,目的用来指示客户端或缓存服务器的缓存功能;
    请求报文中的缓存功能主要目的在于,向服务端发请求时,告诉服务端是否接受缓存中的内容;也可以用于告诉缓存服务器只接受哪种类型的缓存资源;
    缓存控制项包括过期日期,或者加上缓存控制首部来完成缓存内容或缓存服务器中双方进行通信时的缓存控制;
shift+F5就是强制刷新;就是在发送时,在缓存首部加个信息,意思是no-cache或no-store的效果,不能用缓存响应,必须到原始服务器加载;不过,这种请求一般到上一级就停止了,因为缓存是多级的;
    对于http 1.0使用的是缓存有效期,如果是基于有效期验证缓存,只有缓存有效期过期,缓存内容可能会被删掉,无论缓存的数据是否发生改变,缓存服务器都向后端服务器请求数据;所以,原始服务器内容一直没有改变,只要过期都要重新去获取数据,这样效率低;
所以http 1.1使用了另外一种缓存机制,进行新鲜度检测;实现条件式请求首部和有效性再验证;

 

新鲜度检测机制:有效性验证:revalidate
如果原始内容未改变,则仅响应首部信息,不用附带body部分,只提供响应首部,响应码为304(表示未修改Not Modified);
如果原始内容发生改变,则正常响应,响应码为200;跟新请求一样;
如果能够进行有效性再验证,要求向客户端在请求时必须向服务端说明,是做有效性再验证式的请求;而有效性再验证式请求有专门的请求首部;

条件式请求首部:
   1、If-Modified-Since:缓存数据与缓存数据的时间戳进行比对,改变后返回数据并返回200,如果时间戳未改变返回304,由缓存响应,自从某时发生改变,(就响应内容,响应码200);基于原始内容的最近一次修改的时间戳进行有效性验证
   2、If-Unmodified-Since:自从某时没发生改变,(就响应304);
   3、If-Match:如果匹配,后端服务器就不用响应给缓存服务器,返回304响应码
   4、If-None-Match:基于Etag的比较进行;就是对数据的校验码进行比对;数据没变校验码就不会变(就响应304),如果不同则返回响应内容(响应内容,响应码200);
   5、Etag:hash码,给内容加标签。

 


基于条件式首部的控制机制: 

  客户端再次发请求时,缓存服务器收到后进行缓存有效性再验证,因此,向后端原始服务器发请求时首部信息中有:If-Modified-Since信息,如果原始服务器内容未发生改变,则返回没有修改,响应码为304;然后缓存服务器从缓存中加载内容,响应给客户端并在响应首部中有Last-Modified信息,即上一次修改时间信息;
如果原始服务器内容发送改变,则原始服务器响应给缓存服务器内容,响应码为200,同时在响应首部信息有Last-Modified信息;这种基于有效性再验证的方式有一个缺点,缓存内容后,每次都有与后端原始服务器进行通信;可以把基于过期时间的缓存控制方式和基于有效性再验证的方式结合起来;
如果客户端再请求时,如果没过期,则由缓存服务器直接响应给客户端;如果缓存过期,不会直接向原始服务器请求内容也不会把缓存内容删除,而是向后端原始服务器发请求首部信息为进行有效性再验证If-None-Match信息;如果原始服务器发现缓存服务器请求的内容没变,则直接响应304,Not Modified,并告诉缓存服务器可缓存时长Cache-Control:max-age=10信息;
在实际应用场景中,缓存是多级的;但其原理都是一样的;


Varnish:

varnish的Management主控进程主要作用:

应用新配置、编译vcl、监控varnish子进程、初始化varnish、以及提供一个命令行接口;一般Management进程,会每隔几秒钟探测Child进程是否正常运行,如果长时间内没有收到所必须存在的Child进程的响应,则Management会重启此Child子进程,兼具了watchdog功能;Chile进程包含多种类型的线程:
包含Accept线程名字叫accepter,主要作用是接收新请求并响应用户请求的进程;
另外非常重要的线程是Worker threads,主要作用是处理用户请求,child子进程会为每一个用户请求启一个worker线程,worker threads是单线程,单响应的;即是每一个请求用一个独立的线程响应的,而不像nginx中一个worker响应n个请求;所以这样,整个varnish内部要运行n个线程,同时并发处理n个请求,而每一个服务器的并发能力是有限的,所以,对varnish也要定义并发响应上限;通常使用treadpool线程池进行定义;
例如,一个线程池最多可定义2000个线程,如果要想能并发响应6000个请求,那么,可以启动3个线程池;相当于nginx中启动3个worker进程,每个worker进程并发响应2000个请求;但是,对于varnish,内部线程是看不到的,也就是使用ps aux等命令是看不到的;所以,从本质上讲同nginx比较相似;可理解nginx内部也是有线程的,也是看不见的,不是linux管理的独立线程;另外,varnish依赖一个工作区域,以降低线程在申请或修改内存时,出现所谓临界区域的可能性,出现资源竞争的可能;所以说varnish内部存在各种工作区,其中一个叫日志区域SHM;SHM是多个组件都能与之通信,但往里写数据的通常是accept进程或workerthreads进程等的工作线程,而非是查看工具(varnishlog、varnishstat等);所以,varnish为了能够与系统其它部分(其它线程)交互,Child进程使用了可以通过文件接口进行访问的共享内存来进行;这个共享内存区域叫做共享内存日志shared memory log;如果某线程需要记录日志信息,那么该线程只需要持有一个对此内存空间的写锁进程,对内存的读写加锁,释放锁的速度是比较快的;为了减少竞争,几乎每个worker线程都使用了日志缓存,所以它不直接往内存日志区域中写,虽然是共享内存,而是先写到自己的专用缓冲里面,然后在往里同步,所以就这样能较少内存竞争的可能性;varnish共享内存日志空间为90M,以循环方式进行记录;为了能够记录下来,利用多个工具查看里面的内容,也可以把查看的结果保存下来;使用varnishlog或varnishncsa实现;varnish通过可以基于文件系统接口进行访问的共享内存区域来记录日志(shared memory log);默认空间大小为90M;90M共享内存分为两部分:前半部分是计数器:记录了资源被访问的次数、命中次数、未命中次数、已经处理的连接数量等;后半部分为客户端请求的数据;
 
vcl:varnish configuration language-----配置缓存策略的工具;基于“域”的配置语言;使用{};vcl域类似于iptables中的钩子:用户请求到达varnish进程时,先分析请求是否允许,如果不允许则直接丢弃;如果允许则要查缓存,查看是否缓存命中,如果命中,则要到缓存中取内容(要查看缓存是否过期,是否要检查有效性验证等);如果缓存中没命中,要到后端取数据,取内容后,是否要缓存,缓存多长时间,缓存后应如何响应给客户端都可进行控制等等;所以,在不同的位置进行控制,这类似于钩子;在每个位置加上一个钩子,在钩子上写配置项,而这每一个位置就叫做一个域;生效配置只对一个域(位置)有效;vcl是基于域的配置语言,支持使用正则表达式,自定义变量,if语句,还有内置函数等等;vcl策略在启用之前,必须先由management进程转换发送到vcl compiler转换成C代码,接着由GCC编译器将其编译成二进制格式的才能被各Child/cache子进程使用;所以,编写的vcl能生效,要安装gcc编译器;这是个依赖关系;另外,编译后的版本,可以是手动即时加载,但是一旦varnish进程关闭,配置也就消失;配置文件每次启动后,会默认加载编译生效;所以,要把长期使用的vcl配置放在vcl配置文件中,这个配置文件通常需要手动指定位置,且并没有固定格式的文件要求;不过,默认会读取一个default.vcl的配置文件;依赖gcc编译器
 
varnish初始化时,包括调用vcl compiler编译器,用来编写varnish配置文件的,主要作用是配置varnish如何缓存缓存项的,例如哪些内容缓存多长时间,哪些内容不缓存,对用户请求该如何响应等;所以,vcl compiler编译的配置文件是用来控制varnish缓存机制的,而不是控制服务自己该如何运行的;服务自己如何运行是靠命令行选项来控制的,类似于此前介绍的memcached;只不过varnish在内部命令行中也可以动态的及时调整各进程的工作方式、线程池大小等等;vcl compiler通过调用外部的C cpmpiler(C编译器)进行编译,这就要依赖gcc编译器,然后生成一个二进制格式的配置对象,这个二进制格式的配置对象可以被各Child和cache子进程所加载读取相关配置;所以,每一次修改varnish配置文件,都要手动加载、编译、装载、使用;支持动态装载;

1、varnish三部分组成
    Management:主控进程,类似于nginx的master进程; 

     Child/cache:工作进程,Worker进程
    
VCL ccomplier:编译器,当varnish定义之后直接编译就可生效

2、Management组件:
     command line   //负责提供命令行接口,通过命令行程序管理varnish的功能;
    child process mgmt:  //负责管理各种varnish子进程;
    initialisation  //负责初始化缓存空间,加载配置文件,准备缓存目录,还包括调用vcl编译器等;

3、varnish的缓存机制:
 缓存在内存中;性能更好;
缓存在磁盘上;空间更大;

 

4、command line交互接口有三种:
    CLI interface:专用的命令行接口;
    Telnet interface:使用telnet,但无法做验证;
    Web interface:网页图形窗口,是商业版收费使用;

5、Child/cache包括以下组件:
    command line  //命令行接口;
    Storage/hashing   //实现缓存管理,做哈希,存储;
    Log/stats   //日志及数据统计;
    Accept //接收用户请求;
    Backend communicaton  //建立与后端服务器通信的连接;
    Worker threads    //工作线程,负责处理用户请求,例如从缓存加载用户请求内容并响应;
    Object expiry   //做缓存数据的有效性验证、清理等;
    Log file//日志文件
所有接收用户请求,处理请求等的结果保存在日志文件中;默认,这个日志文件不是磁盘文件而是共享的内存空间(SHM);这段内存空间大小的固定的,90M左右,填满后,会滚动覆盖,类似于rrd数据库的工作方式;不能保存太多信息;所以,可以基于某些机制来实现,保存日志信息;

 

6、日志信息相关交互二进制程序工具
    varnishncsa:  //varnish日志文件中规律性的加载数据,保存在磁盘文件中,日志格式类似于httpd中的日志combined类型;
    varnishlog //也是从log file中加载内容,持久保存在文件中;同varnishncsa机制,日志格式是varnish原生的自己日志的格式,非常丰富,冗余信息较多;
    varnishstat//是从log file中读取数据展示出来做分析,提供统计数据;
    varnishtop://是排序功能,跟top命令一样,把资源访问量等信息,进行统计展示后排序显示;例如进程所占用内存空间,cpu时间等;
    varnishhist://查看日志历史信息;

7、varnish缓存内容的存储:
    1、file:存储在磁盘上;自管理的文件系统,是个黑盒;不能重启,否则缓存失效;
    2、malloc:其实使用的是内存缓存机制,即缓存在内存中,使用内存分配的系统调用函数malloc()库调用在varnish启动时,向内存申请指定大小的空间;并将其按固定格式指派,类似于memcached一样的chunk;
    3、persistent:与file功能相同重启后缓存不消失处于测试期;

varnish缓存的存储详解:

file-----存在磁盘文件中,与nginx不同,因为nginx缓存是进行哈希后,用一个目录结构,还可指明目录层级,就是把文件的哈希码,按前几个字符进行目录分层结构,每个一个缓存项是单独一个文件存储的;而varnish的缓存则不是这样存储的,varnish缓存是把所有文件存储在一个文件中,在外部看来是一个巨大的单个文件,其内部是一个黑盒,varnish内部自行管理缓存,它知道到哪去加载缓存文件、缓存文件叫什么名等;用户对其内部管理机制不得而知,还有,基于这种方式缓存的数据,指对当前进程有效,意思是重启后,黑盒得重置,里面的所有缓存全部失效;所以,varnish不能随意重启!Malloc------varnish缓存内容还可使用malloc:其实使用的是内存缓存机制,使用内存分配的系统调用函数:malloc()库调用;一般只有两种选择存储缓存,file机制或malloc机制;如果想基于内存存储缓存,缓存空间不会太大,2G空间放在内存中,否则内存再大,例如20G,不建议使用;因为在内存中基于缓存管理不当的话,会产生内存碎片,造成性能下降;
varnish强调:varnish由于无法追踪某缓存对项是否被存入缓存文件,从而也就无法知道,下次启动以后缓存对象是否依然存在,所以它的缓存是无法重启后生效的;varnish缓存本身,malloc基于内存缓存,它的内存分配策略malloc是非常低的;因为malloc出现较早,对于现今内存空间动辄都是以G为单位分配;malloc显得不太合适宜,所以,后来google就研发了更加强调的malloc分配器,或叫内存申请分配回收工具;可以让varnish为了提升其内存缓存性能,可以把它链接至Google所提供的第三方开源的内存分配器库上去,以实现内存的高效分配和回收;而是以rpm方式安装的varnish默认自动解决这个依赖关系的;varnish反向代理工作时,必须先完成代理后才能缓存;在varnish的场景中,像在nginx中被称作upstream server;应该工作在这些服务器的前端,提供缓存服务;所以,这个缓存服务器应该有两块网卡,内网网卡用来为后端所有(上游服务器)主机使用私有地址通信,也有可能又是一级缓存服务器,外网网卡用来对前端客户端或调度器通信;用户请求先到达varnish,由varnish反代给后端某主机,但varnish也可负载均衡至后端多个主机;varnish也可以对后端主机做健康状态检测;这些基本功能都有,所以说varnish首先得是个代理,其次,才是个缓存,只不过它的缓存功能强于代理功能;因此,在实际使用时,在varnish前端有nginx,nginx负载用户的请求,而一台varnish不能满足用户的请求,要有多个varnish提供缓存服务;这样,nginx就负载均衡用户的请求到多个varnish主机上;varnish自己再反代或负载均衡至后端多个主机;如果varnish前端使用了nginx,就要使用其中的hash url算法即对同一个url请求将发往同一台服务器,这是为了提高varnish缓存命中率;就是无论哪个主机请求的是同一个url,就发往同一个缓存服务器,如果有第一个用户请求过一会,缓存服务器上就会有缓存了,第二个用户再请求同一资源时,因为使用了对url进行hash,就会被发往同一缓存服务器此时缓存就会命中了;
在memcached中的缓存策略时,基于哈希方式进行调度时,哈希的是什么,基于分布式方式调度缓存时有两种方式:取模法和一致性哈希法;


 

 

varnish的程序环境:

/etc/varnish/varnish.params  //配置varnish服务进程的工作特性,例如监听的地址、端口及缓存机制;

/etc/varnish/default.vcl:   //配置各Child/Cache线程的工作属性;

/usr/sbin/varnishd    //主应用程序

/usr/bin/varnishadm     //命令行程序工具

Shared Memory Log交互工具:

/usr/bin/varnishhist  //查看日志历史信息

/usr/bin/varnishlog//从日志文件(配置文件中定义的记录日志的文件)中加载日志内容,持久保存在文件中,日志格式为原有的格式

/usr/bin/varnishncsa//从日志文件中加载日志内容,有规律的使用类似httpd程序记录日志的格式保存日志

/usr/bin/varnishstat//从日志文件读取数据进行分析,提供统计数据进行展示

/usr/bin/varnishtop//将日志信息进行分类排序进行显示

/usr/bin/varnishtest   //测试工具

/usr/sbin/varnish_reload_vcl   //vcl配置文件重新加载程序


 


varnish程序的选项:

即使用命令行命令选项修改/etc/varnish/varnish.params文件中的指令

-a address[:port][,address[:port][...]  //监听使用的默认为6081端口;

-T address[:port]   //管理varnish的监听端口,默认为6082端口;

-s [name=]type[,options]   //定义缓存存储机制(可用file、malloc)

-u user

-g group

-f config:VCL配置文件;

-F:  //设定varnish进程运行于前台;  

-p param=value:设定运行参数及其值;可重复使用多次;

-r param[,param...]: 设定指定的参数为只读状态;


安装varnish:
    # yum install varnish
     # yum info jemalloc  //支持并行内存分配和回收;
# yum info varnish-docs  //varnish的文档包
/usr/share/doc/varnish-docs-4.0.3/html  //把此目录输出到web服务中即可实现查看;
/etc/varnish/default.vcl  //默认的vcl配置文件
/etc/varnish/varnish.params //varnish服务器的参数文件,早期是放在/etc/sysconfig/varnish中;//centos6中此文件名是/etc/sysconfig/varnish,类似于
memcached的一样;
/etc/varnish/secret //密钥文件用于服务端跟varnishadm命令连接时使用;

 

Varnish管理交互界面命令:

# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
    status    //查看varnish缓存服务器状态
    start     //启用varnish缓存服务器
    stop      //停用varnish缓存服务器
    vcl.load <confignam> <filename>    //装载指定的vcl配置文件

         configname 编指定译后的文件名

         filename 指定要编译的文件名
    
vcl.use <confignam>//使用指定的装载名的vcl
     
vcl.list    //列出vcl缓存策略配置文件
    backend.list     //列出后端主机
    backend.set_health <backend_expression> <state>    //设定后端主机状态
    storage.list    //显示缓存存储的类型
    ping     //测试varnish缓存服务器是否在线
    vcl.discard <configname> 删除vcl配置文件命令
    vcl.show [-v] <configname> 查看vcl配置文件命令

 

 

 

配置varnish工作进程特性文件详解:

[root@Centos7-1 varnish]# egrep "^[^(#|[:space:])].*"  /etc/varnish/varnish.params

    RELOAD_VCL=1     //使用reload而不是restart命令加载服务时,可自动重新加载vcl配置文件,是vcl文件重新生效

    VARNISH_VCL_CONF=/etc/varnish/default.vcl  //设置加载的vcl配置文件

    VARNISH_LISTEN_PORT=6081     //设定varnish监听的端口

    VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1    //设定管理varnish服务的地址

    VARNISH_ADMIN_LISTEN_PORT=6082//设定管理varnish服务监听的端口

    VARNISH_SECRET_FILE=/etc/varnish/secret    //varnish链接管理地址时使用的认证共享秘钥文件

    VARNISH_STORAGE="file,/var/lib/varnish/varnish_storage.bin,1G"   //设定varnish缓存的格式为file类型,并指定文件路径,为二进制格式的文件,大小为1G

    VARNISH_TTL=120//如果后端服务器没指定生存时长,就使用此处的默认值

    VARNISH_USER=varnish//运行varnish工作进行的属主

    VARNISH_GROUP=varnish//运行varnish工作进程的属组

    DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300"     //设定运行时的参数为指定的值,这些运行时参数,都可以使用-p param=value指定;

 

状态引擎:vcl每一个状态引擎是一个子例程subroutines;
面向客户端:状态引擎:

    vcl_recv:    //收到请求,在此处判定请求方法,如果是get或head,则送给vcl_hash引擎,因为是可缓存的;如果用的是其它方法就送给vcl_fetch()引擎,到后端取数据;
    vcl_hash    //查找缓存,有可能命中或未命中,命中就交给vcl_hit()引擎,未命中交给vcl_miss()引擎;
    vcl_hit()    //命中,到缓存中取数据,然后交给vcl_deliver()响应给客户端;
    vcl_miss()   //未命中就交给vcl_fetch()到后端取数据;
    vcl_fetch()  //到后端服务器读取数据;
    vcl_deliver():  //构建响应报文响应给客户端;
与后端服务器相关:
    vcl_backend_fetch   //获取后端数据
    vcl_backend_repose   //收到后端响应
    vcl_backend_error   //后端无数据
    vcl_synth   //数据同步完成;
    vcl_deliver   //响应给客户端


vcl的语法:
    1)//,#,/*...*/:注释符;
    (2)sub $name:定义子例程;
    (3)不支持循环,支持条件判断;
    (4)与引擎香相关的内置变量
    (5)使用终止语句return,没有返回值;
    6)操作符:=赋值,==等值比较,!==不等值比较,~模式匹配,&&,||

        
内建变量:
    req.*:由客户端发来的http请求相关;
    req.http.*:请求报文的各首部;
    bereq.*:由varnish向backend主机发出的http请求;
    bereq.http.*:发往后端请求报文的http首部;
    beresp.*:由backend主机发来的http响应报文;判断是否缓存;
    beresp.http.*:后端服务器响应报文中的http各首部;
    resp.*:由varnish响应给client的http的响应报文;
    resp.http.*:响应报文的各首部值;
    obj.*:存储在缓存空间中的缓存对象属性;只读;
    client.*,server.*,storage.*:可用在所有的client side的sub routines中;

常用的变量:
     bereq:发给后端主机用到的变量
    bereq.http.HEADERS:可定义的首部;
    berq.request:向后端服务器发送请求文本时的请求方法;
    bereq.url:请求的url;
    bereq.proto:协议版本;
    bereq.backend:指明要调用的后端主机;
    beresp:后端服务器响应的可用变量
    beresp.proto:后端服务器响应报文首部的协议
    beresp.status:后端响应的状态码;
    beresp.reason:后端响应原因短语;
    beresp.backend.name:后端响应报文首部,表示后端服务器名称;
    beresp.http.HEADERS:后端响应http的其它各首部;
    beresp.ttl:后端服务器响应中的内容的余下的生存时长;

         

 

VCL的内置函数

regsub(str,regex,sub)

regsuball(str,regex,sub):这两个用于基于正则表达式搜索指定的字符串并将其替换为指定的字符串;但regsuball()可以将str中能够被regex匹配到的字符串统统替换为sub,regsub()只替换一次;

ban(expression):

ban_url(regex):Bans所有其URL能够由regex匹配的缓存对象;

purge:从缓存中挑选出某对象以及其相关变种一并删除,这可以通过HTTP协议的PURGE方法完成;

hash_data(str):

return():当某VCL域运行结束时将控制权返回给Varnish,并指示Varnish如何进行后续的动作;其可以返回的指令包括:lookup、pass、pipe、hit_for_pass、fetch、deliver和hash等;但某特定域可能仅能返回某些特定的指令,而非前面列出的全部指令;

return(restart):重新运行整个VCL,即重新从vcl_recv开始进行处理;每一次重启都会增加req.restarts变量中的值,而max_restarts参数则用于限定最大重启次数。

 

 

 


 

 

 

实验示例:

VCL默认配置文件详解:/etc/varnish/default.vcl

# vim /etc/varnish/default.vcl
    backend default { 定义默认后端服务器
        .host = "127.0.0.1"; 后端服务器ip地址]
        .port = "8080"; 后服务器监听的端口} 
    sub vcl_recv {此处做请求清理时使用,移除用户请求是绑定cookies信息,因为主机用户请求的资源不是个人的页面或邮箱私有数据,对公共资源请求加工也没有意义的,而且会导致缓存无法命中;
    } 
    sub vcl_backend_response {
        从后端服务器收到响应报文之后可采取的处理;
        } 
    sub vcl_deliver {
        把响应报文发给客户端之前可采取的处理;
        }



示例1: 定义代理缓存服务器,并连接至后端服务器

[root@Centos7-1 ~ ]# vim /etc/varnish/default.vcl
    backend default {        //定义后端服务器
        .host = "10.1.25.11;//后端服务器地址
        .port = "80";//定义后端服务器端口} 
[root@Centos7-1 ~ ]#  systemctl start varnish.service  //启动varnish服务
[root@Centos7-1 ~ ]#  varnishadmin -S /etc/varnish/secret -T 127.0.0.1:6082   //登录varnish管理界面进行加载vcl配置
Varnish> vcl.load  test1 default.vcl   //加载vcl配置,名称为test1 
Varnish> vcl.list //查看当前活动的vcl
Varnish> vcl.use test1  //设定使用vcl

 

示例2:添加是否启用缓存响应的响应首部

[root@Centos7-1 varnish]# vim default.vcl    
    backend default {        //定义后端服务器    
     .host = "10.1.25.11;//后端服务器地址    
     .port = "80";//定义后端服务器端口   } 
    sub vcl_deliver {    //在缓存服务器响应报文给客户端的配置段中添加条件判断                if (obj.hits>0) { //变量obj.hits表示命中次数      
                set resp.http.X-cache = "HIT from " + server.ip;   //响应给客户端报文变量,http首部中自定义一个首部为X-cache,其值设为HIT    
              } else {       
                  set resp.http.x-cache = "MISS from " + server.ip ;    
              }
 }


[root@Centos7-1 ~ ]#  varnishadmin -S /etc/varnish/secret -T 127.0.0.1:6082   //登录varnish管理界面进行加载vcl配置

Varnish> vcl.load  test2 default.vcl   //加载vcl配置,名称为test2

Varnish> vcl.use test2  //设定使用vcl

含义:当客户端向缓存服务器请求资源时,缓存服务器会根据自己的缓存引擎逐一进行匹配,当缓存个服务器在查询到客户端请求的资源进行响应时,在进行响应是设定条件判断进行来匹配是否添加指定报文

匹配过程:设定命中率函数,如果资源从缓存中响应,则等于1,否则等于0,先判断响应的对象是否从缓存服务器中进行响应的,如果是从缓存服务器中进行响应的,则obj.hits=1,则条件满足,添加http响应报文X-cache,值(为HIT from 缓存服务器IP),否则为MISS

 

 

 

 

 

示例3:强制对某资源的请求不检查缓存:检查请求内容包含:/admin,/login,不检查缓存也不允许缓存

]# vim /etc/varnish/default.vclbackend RS1 {         //定义后端服务器
 .host = "10.1.25.11";//后端服务器地址
 .port = "80"//后端服务器服务监听端口
}
Sub vcl_recv {//客户端请求报文到达缓存服务器使用条件判断语句判断客户端请求的url是否匹配,如果匹配,则使用return函数返回pass引擎,表示为用户的私有数据通道,不能查找缓存进行响应,后端服务器进行响应时也不能将此数据缓存下来。
 If (req.url ~ "(?i)$/admin/?" || "(?i)$/login/? " ){  //不区分大小写进行匹配判断,匹配到其中一个都算匹配成功
 Return(pass);   //如果条件匹配成功,则返回pass引擎
 }
}
Sub vcl_deliver {//在缓存服务器构建响应报文响应给客户端时进行条件判断缓存是否命中进行添加http响应首部
 if (obj.hits>0) {
 set resp.http.X-cache = "HIT from " + server.ip;
 } else {
 set resp.http.X-cache = "MISS from " + server.ip;
 } 
}
[root@Centos7-1 ~ ]#  varnishadmin -S /etc/varnish/secret -T 127.0.0.1:6082   //登录varnish管理界面进行加载vcl配置
Varnish> vcl.load  test3 default.vcl   //加载vcl配置,名称为test1 
Varnish> vcl.use test3 //设定使用vcl
 
验证:
[root@Centos6-1 ~]# curl -i 10.1.25.4:6081/admin/   //第一次请求
HTTP/1.1 200 OK
Date: Fri, 28 Oct 2016 20:13:12 GMT
X-cache: Miss from 10.1.25.4
 
[root@Centos6-1 ~]# curl -i 10.1.25.4:6081/admin/index.html   //第二次请求
HTTP/1.1 200 OK
Date: Fri, 28 Oct 2016 20:13:45 GMT
X-cache: Miss from 10.1.25.4
 
注意:测试时,如果匹配的为最后的uri资源,则测试时需要补全uri,若是最后一个资源的目录则不需要补全


 

 

 

示例4:对客户端访问特定资源进行取消cookie标识提高缓存命中率

对于特定类型的资源,可以取消cookie标识;一般缓存服务器看到cookie是避免缓存的,也会尽量避免从缓存中取数据,因此会导致缓存命中率下降;所以,对这种公开资源可以取消cookie标识,就可大大提升缓存命令率;

# vim /etc/varnish/default.vcl
    sub vcl_backend_response {  //在后端服务器响应给缓存服务器的引擎上做条件匹配
        if (bereq.url ~ "(?i)\.jpg") {     //如果客户端请求的是.jpg结尾的图片时,则匹配成功,则取消该资源的cookie信息,设定该资源的可以缓存在缓存服务器,并设定缓存时长为7200s;
           if (beresp.http.cache-control !~ "s-maxage") {    //对后端服务器响应给缓存服务器的响应报文中的http协议的报文中的cache-control首部的值如果不是s-maxage,则表示条件匹配成功,;
     unset beresp.http.Set-Cookie; 如果后端服务器响应报文http首部中Set-Cookie,则删除这个首部
     set beresp.ttl = 7200s; 设定后端服务器响应报文中可缓存的时长,存入缓存就开始倒计时}    }
}

配置含义:当客户端访问一个指定资源时,如图片,为避免此资源设定cookie信息在资源上,从而缓存服务器命中率则下降,定义此vcl则是将客户端请求的资源去掉cookie信息,将此资源缓存到缓存服务器,提高缓存服务器的资源命中率,因为varnish是不缓存带有cookie信息的资源,所以需要设定是公共资源的却有cookie信息的将其删除cookie信息

注意:
1.如果是get或head都可以缓存;
2.通常只对静态资源进行缓存;可以让静态资源不使用缓存时长的默认值,而自定义缓存时长;
动态资源其实也可以缓存,只不过由动态服务器自己设定缓存时长的;varnish反代服务器只需要指向动态服务器就行了;
对特定类型的资源,例如公开的图片等,取消其私有标识,并强行设定其可以由varnish缓存的时长;

vcl_backend_response:
if (beresp.http.cache-control !~ "s-maxage") {
if (bereq.url ~ "(?i)\.jpg") {
set beresp.ttl = 7200s;
unset beresp.http.Set-Cookie;
}


 


示例5:对缓存进行修剪

[root@Centos7-1 ~]# vim /etc/varnish/default.vcl 
acl purges {      //设定指定清理缓存的可使用的地址,使用acl来控制如果要清理缓存,必须使用此处指定的地址
"127.0.0.0"/8;
"192.168.1.40"/24;
}
sub vcl_recv {//在varnish接收客户端请求的第一个引擎上做条件判断,因为需要先查看用户的请求方法是否为purge,再进行其他操作
if (req.method == "purge" ){ //定义如果客户端的请求方法此处指定的字符串(可自定义名称),则再次进行下一级判断
if (client.ip ~ purges){//如果请求方法为purge,则判断使用purge方法的ip是否能够匹配acl中定义的ip,如果能,执行return函数,调用vcl_purge引擎,执行清理缓存操作,并且响应码为200,原因短语为purged
return(purge);     //需要指定此项才能清除缓存
}
return(synth(403,"Sorry"));   //如果请求方法为purge,但使用purge方法的ip不能匹配acl成功,则返回403的响应码,原因短语为Sorry。
}
}
sub vcl_purge {    //定义purge引擎,如果有ruturn返回执行的动作为purge时,调用此引擎进行执行清理缓存,并返回响应码及原因短语return(synth(200,"Purged")); }



如果只是想基于某种方式清理或删除单个缓存项,可以在命中以后执行相应操作;

例如:可以在hit中命中时用户的请求方法是purge时,来对某些资源执行在缓存中的删除操作;

注意:缓存修剪方式与varnish 3.0版本不一样;
例如:在varnish3.0上,缓存在命中时做purge

sub vcl_hit {
if (req.method == "PURGE") {
purge;
error 200 "Purged";
}
}


 

 

 

 

 

示例6:配置varnish动静态资源分别进行反代

varnish还可实现访问静态资源是反代给后端一台主机,访问动态资源是反代至另一台主机;
[root@Centos7-1 ~]# vim /etc/varnish/default.vcl
    Sub vcl_recv {//在客户端请求到达缓存服务器时就进行分析处理报文
        backend php {    //定义后端动态服务器
        .host = "10.1.25.1";//定义后端动态服务器地址
        .port = "80";//定义监听的端口}
    Backend websrv {//定义后端静态服务器
     .host = "10.1.25.11"//定义后端静态服务器地址
     .port = "80"//定义监听的端口
    }
    if (req.url ~ "(?i)\.php$") {//定义如果客户端请求的uri以.php结尾则设定指定使用后端服务器名为phpsrv的服务器进行处理,
        set req.backend_hint = phpsrv;
    } else {//如果请求的资源不是以.php结尾的,则再次判断是否以/index.html结尾,如果是则命中后端服务器名为websrv的服务器进行处理,并return引擎为pass,不通过缓存进行响应,也不让缓存。
        if (req.url ~ "^/index.html$"){
           set req.backend_hint = websrv;
        return(pass);
        }    
    }
}


 

 

示例7:对后端多个主机做负载均衡,使用:vcl_init子例程,创建一个负载均衡器;实现动静分离调度

[root@Centos7-1 ~]# vim /etc/varnish/default.vcl 
Impport directors;   //加载调度算法模块
backend phpsrv {       //定义后端动态服务器
    .host = "10.1.25.11";
    .port = "80";
}
backend websrv {//定义后端静态服务器
.host = "10.1.25.1";
.port = "80";
}
sub vcl_init {//定义初始化引擎,
new websrvs=directors.round_robin();//定义一个新组,名称为websrvs,调度算法为轮循
websrvs.add_backend(websrv);//在websrvs组中添加后端服务器,
websrvs.add_backend(phpsrv);
}
sub vcl_recv {//在缓存服务器中第一个引擎中设定客户端的请求命中到websrvs组中,由websrvs组来轮循调度主机
set req.backend_hint=websrvs.backend();
if (req.url ~ "(?i)^/index.html$"){ //设定请求的资源为index.html是不进行查找缓存和将查询的结果缓存到服务器,因为pass通道为用户的私有数据信息,不运行缓存
 Return(pass);
}
}
[root@Centos7-1 varnish]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
Varnish>vcl.load  test5 default.vcl
Varnish>vcl.use  test5 
验证:会在两台后端主机中轮循调度,使用资源为index.php时会调度到phpsrv主机
[root@CentosTab ~]# curl http://10.1.25.4:6081/index.html
RS1 CentosLab PHP  Server 
[root@CentosTab ~]# curl http://10.1.25.4:6081/index.html
RS2 Centos6-1: WEB Server


 


示例8:对后端主机做健康状态检测:

[root@Centos7-1 ~]# vim /etc/varnish/default.vcl 
import directors;   //加载调度模块
probe check {//定义健康状态检测,名称为check
.url = "/index.html";//定义检测的url,必须存在,否则为检测失败
.window = 5;//定义检测的次数
.threshold = 4;//定义在.window指定的次数中,多少次检测ok才算检测成功
.timeout = 3s;//定义检测时的请求的超时时间
.interval = 1s;//定义检测的间隔时间
.expected_response = 200;//定义期望的响应码为200
}
backend phpsrv {
    .host = "10.1.25.11";
    .port = "80";
.probe = check;//调用健康状态检测
}
backend websrv {
.host = "10.1.25.1";
.port = "80";
.probe = check;调用健康状态检测
}
sub vcl_init {
new websrvs=directors.round_robin();
websrvs.add_backend(websrv);
websrvs.add_backend(phpsrv);
}
sub vcl_recv {
set req.backend_hint=websrvs.backend();
 
[root@Centos7-1 varnish]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
Varnish>vcl.load  test8 default.vcl
Varnish>vcl.use  test8 
varnish> backend.list    //列出后端服务器的状态信息
200        
Backend name                   Refs   Admin      Probe
phpsrv(10.1.25.11,,80)         3      probe      Healthy 5/5
websrv(10.1.25.1,,80)          3      probe      Healthy 5/5
 //Probe中的Healthy为5 /5则证明健康状态检测成功
手动标记服务器为不可用及恢复可用:
Varnish> backend.set_health  phpsrv sick    //手动将phpsrv服务器标记为不可用
 Varnish> backend.set_health  phpsrv Healthy//手动将服务器变为可用


 

 

 

varnish的运行时参数:

线程模型:类似于http的event模型,
cache-worker :专用于处理请求的线程
cache-main:
ban lurker:对缓存中的缓存进行清理的进行
acceptor: 专用于接受用户请求的,接收后由worker进程进行处理
epoll/kqueue: epoll用来完成单进程处理多请求

需要调整的运行时参数:线程相关的参数

在线程池内部,其每一个请求由一个线程来处理; 其worker线程的最大数决定了varnish的并发响应能力;
Varnish的最大并发连接数=t线程池数量(hread_pools)  *  每个线程池的最大线程数(thread_pool_max)
thread_pools:线程池,类似于nginx的worker process,线程池的数量应该小于或等于CPU核心数量; 
thread_pool_max:定义每个线程池的最大worker线程数量,不包含其他线程,每一个worker进程处理一个用户请求
 thread_pool_min:定义每个线程池的最少工作线程数,也意义为“最大空闲线程数”;
thread_pool_timeout:  定义每个线程的空闲超时时长,一个工作线程超出此时长将会被kill,注意:保留的最少线程数不能少于thread_pool_min所定义的线程数量
thread_pool_add_delay: //创建一个线程之前不能立即创建,因为在创建线程的时间内可能有线程空闲,此定义在创建进程之前延迟指定时长
thread_pool_destroy_delay://在thread_pool_min定义的超时时长之后处理线程时,为避免临时涌进大量请求,延迟指定时长在清理超时线程


定义方式:

临时有效:Varnish> param.set <param> <value>
永久有效:/etc/varnish/varnish.params
 修改:#DAEMON_OPTS="-p thread_pool_min=5 [-r] -p thread_pool_max=500 -p thread_pool_timeout=300"   //可以在参数前加-r 表示为不能在运行时修改
varnish>param.show thread_pool_max  //查看线程池的最大线程数,正常工作稳定值为5000


 

 

 

 

 

varnish日志区域:share memory log
这些值都是不断的抽取内存日志的数据来显示的;varnish的内存空间分成两段,第一段的计数器,第二段是日志数据

 

1、查看计数器:使用varnishstat命令

Varnishstat -1 :   //只显示一次计数器统计信息
Varnishstat -1 -f MAIN.threads :  //只显示一次指定的一个字段的值
Varnishstat  -f MAIN.threads -f MAIN.s_req :  //动态显示指定的字段的值
 
重点关注字段:命中数:MAIN.cache_hit
未命中数:MAIN.cache_miss  
文档命中率:命中率等于hit/(hits+miss)


 

 

2、查看排序后的日志信息:varnishtop命令

根据出现的次数,访问的次数进行排序显示

语法:varnishtop [-1] [-C][-i taglist] [-I <[taglist:]regex>] [-T seconds] [-x taglist] [-X <[taglist:]regex>] [-V]
-I <[taglist:]regex>:被正则表达式匹配的才显示;
-X <[taglist:]regex>:被正则表达式匹配的不予显示;不匹配的才显示;

使用示例:

Varnishtop -1:  //快速查看一次请求日志中的信息
Varnishtop -1 -i ReqHeader :  //查看指定的日志标签信息 varnishtop -1 -i BereqHeader:  //查看所有发往后端服务器的请求报文首部和值
Varnishtop -x -i BereqHeader:  //排除查看指定的报文的其他报文首部及值 
Varnishtop -C -I ReqHeader:User-agent   //查看客户端请求的报文中如果出现指定的报文首部(User-Agent),则查看指定的报文首部(User-agent)的值
Varnishtop -I ReqURL:/login  //查看客户端请求报文中的URL包含login的信息


 


3、查看单条日志内容:varnishlog命令

每一次请求都会被单独记录下来,记录一次请求的请求报文日志记录、响应报文的日志记录分别进行记录

  Varnishlog   //显示每一个请求的详细信息
*   << BeReq    >> 9 //向后端服务器请求报文相关的日志信息
*   << Request  >> 8 //请求报文相关的日志信息
*   << Session  >> 7    //会话相关的日志信息


4、查看类似http格式的日志信息:varnishncsa命令

Varnishncsa

  注意:记录日志的默认空间为90M,当空间存满之后可以使用varnishncsa命令从定向保存

 

5、持续输出日志:启动varnishncas服务

#service varnishncsa start   //会持续记录日志到/var/log/varnish/varnishncsa.log文件中

 

 

 

 

总结:

面向客户端一侧常用的状态引擎:

vcl_init   //初始化,定义后端服务器组时使用,new一个新组调度后端服务器,需要使用import Directors;指定
vcl_recv   //在收到用户请求时想处理的引擎(如访问控制,是否缓存等控制)vcl_hash //hash用户请求的url等数据判定是否需要差缓存的
vcl_hit //hash之后结果命中缓存则使用vcl_hit 引擎处理请求
vcl_miss//hash之后结果为命中缓存则使用vcl_miss或pass引擎处理请求vcl_pass//请求到大pass引擎前提有三种:1.hash以后直接发送到pass,表示此资源为用户的是有数据,不能通过缓存进行响应,2.hit之后也可以发送给pass  3.miss以后也可以发送给pass
vcl_pipe //缓存服务器不理解用户请求的方法(一般缓存服务器只处理GET和HEAD两种方式),则发送给pipe引擎直接使用管道连接后端服务器 
vcl_waiting//当hash引擎过于繁忙时不能及时用户请求,则将用户请求发送到waiting引擎等待处理
vcl_purge //用户请求为purge操作(清理缓存)时,在recv引擎之后return一个purge引擎进行清理缓存
vcl_synth//缓存清理完成或未完成是构建响应报文发送给客户端
vcl_deliver//无论资源从缓存中查询到或是后端服务器请求的都必须经过deliver引擎构建响应报文发送给客户端
vcl_fini//清理上方所定义的操作时使用



面向后端服务器一侧常用的状态引擎:

vcl_backend_fetch//缓存服务器未命中或不允许缓存时使用fetch引擎在后端服务器拿取数据时使用,fetch之后的操作有可能是正常响应(response)或响应错误(error)
vcl_backend_response
vcl_backend_error   //定义响应错误时应该进行的操作


定义状态引擎方法:

sub VCL_STATE_ENGINE   //定义状态引擎,可使用面向客户端或服务端的所有状态引擎,每一个状态引擎都有默认的配置,
backend BE_NAME {}  //定义后端服务器,调用后端服务器时使用set.backend_hint = 后端服务器名称来调用
probe PB_NAME {}//定义健康状态检测机制
acl ACL_NAME {}//定义访问控制列表


 

 

 

缓存服务器空间不够使用的解决办法:

1.增大缓存空间,但内存及varnish自身并发响应有限制

2.增加varnish主机,需要进行调度,在进行调度时要考虑缓存命中率

(对同一个url请求的资源要发送同一个缓存服务器,需要基于url进行hash调度,有两种调度算法:1.如果不添加con...  表示使用取模的调度算法进行调度,任何主机宕机都可能影响取模的结果而调度的结果不一致; 2.使用一致性hash算法进行调度(nginx的upstream中的hash指令#hash $request_uri;),如果前端调度器使用的是nginx Proxy时,需要绑定会话则调度动态资源需使用hash cookie来至同一个用户的请求发往同一个动态服务器)

 

 

 

 

 

练习示例:

1.动静分离调度,其中静态轮循调度

2.设定清除缓存的控制

3.设定健康状态检测

4.添加响应报文

5.....

[root@Centos7-1 varnish]# cat default.vcl
vcl 4.0;//varnish4.0版本中必须首行声明版本信息
import directors;//加载调度算法使用的模块
probe check {//定义健康状态检测
.url = "/index.html";//检测url
.timeout = 2s;//检测超时时长
.interval = 1s;//检测间隔时间
.window = 5;//定义检测次数
.threshold = 4;//定义检测次数中至少必须几次成功,才能判断为OK
.expected_response = 200;//设定期望的响应码
}
backend phpsrv {//定义后端服务器
     .host = "10.1.25.11";
    .port = "80";
.probe = check;//调用健康状态检测
}
backend websrv {//定义后端服务器检测
.host = "10.1.25.1";
.port = "80";
.probe = check;//调用健康状态检测
}
 
acl purge {//定义允许清理缓存的acl控制列表,只有使用此处定义的ip才能清除缓存
"127.0.0.1"/8;
"10.1.25.4"/16;
}
sub vcl_purge {//定义purge引擎,用于清除条件满足时调用此引擎清理缓存并返回数据同步成功信息,响应码为200.原因短语为purged
return(synth(200,"purged"));
}
 
sub vcl_init {//定义初始化引擎,用于定义后端服务器组
new websrvs = directors.round_robin();//添加一个新组,组名为websrvs,调度算法为轮循
websrvs.add_backend(websrv);//为调度组(websrvs)添加后端服务器
websrvs.add_backend(phpsrv);//为调度组(websrvs)添加后端服务器
}
sub vcl_recv {//在处理用户请求的第一个引擎中定义缓存规则
if (req.url ~ "(?i)\.php$") {//定义如果请求的url-匹配以.php结尾,则设定请求报文中添加指定使用命成为phpsrv的服务器进行响应
set req.backend_hint = phpsrv;
} else {//如果不是.php结尾的请求则设定调度到名为websrvs的调度组进行响应
set req.backend_hint = websrvs.backend();
}
if (req.url ~ "(?i)^/(admin|login).*"){//设定如果请求的url包含有admin或login或index.html时,不能查询缓存进行响应,也不能将此资源缓存在缓存服务器中
return(pass);
}
if (req.url ~ "(?i)^/index.html$"){
return(pass);
}
if (req.method == "purge"){//定义如果请求的方法为purge时,清理缓存
if (client.ip ~ purge ) {//如果请求方法为purge,并且客户端的ip为名为purge的acl控制列表中的ip时,调用purge引擎,进行清理缓存,并且响应状态码及原因短语给客户端
return(purge);
} else {//如果请求方法为purge,但请求的ip不匹配acl中定义的ip,则放回不清除的信息
return(synth(403,"Sorry, Purge cache Failed"));
}
}
}
 
sub vcl_backend_response {//当客户端请求的资源在缓存服务器未命中或不能查询的资源时,请求到后端服务器查询到资源,并准备响应给客户端的引擎上添加条件判断信息,如果请求的资源为.jpg结尾的资源,并且服务器在响应给客户端的响应报文中cache-control中的值不能被s-maxage匹配时,则去掉改资源附带的cookie信息,并添加缓存服务器可缓存此资源的时长报文首部
if (bereq.url ~ "(?i)\.jpg") {
if (beresp.http.cache-contro !~ "s-maxage") {
unset beresp.http.Set-Cookie;
 set beresp.ttl = 7200s;
}
}
}
 
sub vcl_deliver {//在缓存服务器准备构建响应报文返回给客户端时添加条件匹配,每一个响应报文必须必须经过deliver引擎响应给客户端
if (obj.hits>0){//如果资源时缓存服务中命中的资源,则添加响应报文为X-cache,值为“HIT From 缓存服务IP”给客户端,否则添加响应报文为“MISS  From  ...”给客户端
set resp.http.X-cache = "HIT from " + server.ip;
} else {
set resp.http.X-cache = "Miss from " + server.ip;  
}
}


 

 

 

 

 

 

 

 

 

 

 

 

 

VCL 内置公共变量

VCL 内置的公共变量可以用在不同的 VCL 函数中,下面根据使用的不同阶段进行介绍

当请求到达时,可以使用的公共变量表 1 所示

1. 请求到达时可用公共变量

公共变量名

含义

req.backend

指定对应的后端主机

server.ip

表示服务器 IP

client.ip

表示客户端 IP

req.quest

只是请求的类型,例如 GETHEAD

req.url

指定请求的地址

req.proto

表示客户端发起请求的 HTTP 协议版本

req.http.header

表示对应请求中的 HTTP 头部信息

req.restarts

表示重启次数,默认最大值为 4

Varnish 在向后端主机请求时,可是用的公共变量如表 2 所示

2. 向后端主机请求时可用公共变量

公共变量名

含义

beresp.requset

指定请求类型,例如 GETHEAD

beresp.url

表示请求地址

beresp.proto

表示客户端发起请求的 HTTP 协议版本

beresp.http.header

表示对应请求中 HTTP 头部信息

beresp.ttl

表示缓存的生存周期,cache 保留时间(s

cache 或是后端主机获取内容后,可以使用的公共变量如表 3 所示

3. 后端主机获取内容时可使用公共变量

公共变量名

含义

obj.status

返回内容的请求状态码,例如 200302504

obj.cacheable

返回的内容是否可以缓存

obj.valid

是否有效的 HTTP 请求

obj.response

返回内容的请求状态信息

obj.proto

返回内容的 HTTP 版本

obj.ttl

返回内容的生存周期,也就是缓存时间,单位秒

obj.lastuse

返回上一次请求到现在的时间间隔,单位秒

对客户端应答时,可以使用的公共变量如表 4 所示

4. 对客户端相应时可使用公共变量

公共变量名称

含义

resp.status

返回给客户端的 HTTP 代码状态

resp.proto

返回给客户端的 HTTP 协议版本

resp.http.header

返回给客户端的 HTTP 头部消息

resp.response

返回给客户端的 HTTP 头部状态

 

 


varnish基础应用