大纲
一、什么是varnish
二、varnish系统架构
三、varnish工作流程
四、varnish日志
五、VCL概念介绍
六、varnish的后端存储
七、Varnish状态引擎(state engine)
八、varnish配置示例
一、什么是varnish
Varnish 是一款高性能且开源的反向代理服务器和 HTTP 加速器,其采用全新的软件体系机构,和现在的硬件体系紧密配合,与传统的 squid 相比,varnish 具有性能更高、速度更快、管理更加方便等诸多优点,很多大型的网站都开始尝试使用 varnish 来替换 squid,这些都促进 varnish 迅速发展起来。
挪威的最大的在线报纸 Verdens Gang(vg.no) 使用 3 台 Varnish 代替了原来的 12 台 Squid,性能比以前更好,这是 Varnish 最成功的应用案例。
二、varnish系统架构
varnish主要运行两个进程:Management进程和Child进程(也叫Cache进程)。
Management进程主要实现应用新的配置、编译VCL、监控varnish、初始化varnish以及提供一个命令行接口等。Management进程会每隔几秒钟探测一下Child进程以判断其是否正常运行,如果在指定的时长内未得到Child进程的回应,Management将会重启此Child进程。
Child进程包含多种类型的线程,常见的如:
Acceptor线程:接收新的连接请求并响应;
Worker线程:child进程会为每个会话启动一个worker线程,因此,在高并发的场景中可能会出现数百个worker线程甚至更多;
Expiry线程:从缓存中清理过期内容;
Varnish依赖“工作区(workspace)”以降低线程在申请或修改内存时出现竞争的可能性。在varnish内部有多种不同的工作区,其中最关键的当属用于管理会话数据的session工作区。
Varnish与一般服务器软件类似,分为master(management)进程和child(worker,主要做cache的工作)进程。master进程读入命令,进行一些初始化,然后fork并监控child进程。child进程分配若干线程进行工作,主要包括一些管理线程和很多woker线程。
针对文件缓存部分,master读入存储配置(-s file[,path[,size[,granularity]]] ),调用合适的存储类型,然后创建/读入相应大小的缓存大文件。接着,master初始化管理该存储空间的结构体。这些变量都是全局变量,在fork以后会被child进程所继承(包括文件描述符)。
在child进程主线程初始化过程中,将前面打开的存储大文件整个mmap到内存中(如果超出系统的虚拟内存,mmap失败,进程会减少原来的配置mmap大小,然后继续mmap),此时创建并初始化空闲存储结构体,挂到存储管理结构体,以待分配。
接着,真正的工作开始,Varnish的某个负责接受新HTTP连接的线程开始等待用户,如果有新的HTTP连接过来,它总负责接收,然后叫醒某个等待中的线程,并把具体的处理过程交给它。Worker线程读入HTTP请求的URI,查找已有的object,如果命中则直接返回并回复用户。如果没有命中,则需要将所请求的内容,从后端服务器中取过来,存到缓存中,然后再回复。
分配缓存的过程是这样的:它根据所读到object的大小,创建相应大小的缓存文件。为了读写方便,程序会把每个object的大小变为最接近其大小的内存页面倍数。然后从现有的空闲存储结构体中查找,找到最合适的大小的空闲存储块,分配给它。如果空闲块没有用完,就把多余的内存另外组成一个空闲存储块,挂到管理结构体上。如果缓存已满,就根据LRU机制,把最旧的object释放掉。
释放缓存的过程是这样的:有一个超时线程,检测缓存中所有object的生存期,如果超初设定的TTL(Time To Live)没有被访问,就删除之,并且释放相应的结构体及存储内存。注意释放时会检查该存储内存块前面或后面的空闲内存块,如果前面或后面的空闲内存和该释放内存是连续的,就将它们合并成更大一块内存。
整个文件缓存的管理,没有考虑文件与内存的关系,实际上是将所有的object都考虑是在内存中,如果系统内存不足,系统会自动将其换到swap空间,而不需要varnish程序去控制。
三、varnish工作流程
vcl_recv:用于接收和处理请求;当请求到达并成功接收后被调用,通过判断请求的数据来决定如何处理请求;
vcl_pipe:此函数在进入pipe模式时被调用,用于将请求直接传递至后端主机,并将后端响应原样返回客户端;
vcl_pass:此函数在进入pass模式时被调用,用于将请求直接传递至后端主机,但后端主机的响应并不缓存直接返回客户端;
vcl_hit:在执行 lookup 指令后,在缓存中找到请求的内容后将自动调用该函数;
vcl_miss:在执行 lookup 指令后,在缓存中没有找到请求的内容时自动调用该方法,此函数可用于判断是否需要从后端服务器获取内容;
vcl_hash:在vcl_recv调用后为请求创建一个hash值时,调用此函数;此hash值将作为varnish中搜索缓存对象的key;
vcl_purge:pruge操作执行后调用此函数,可用于构建一个响应;
vcl_deliver:将在缓存中找到请求的内容发送给客户端前调用此方法;
vcl_backend_fetch:向后端主机发送请求前,调用此函数,可修改发往后端的请求;
vcl_backend_response:获得后端主机的响应后,可调用此函数;
vcl_backend_error:当从后端主机获取源文件失败时,调用此函数;
vcl_init:VCL加载时调用此函数,经常用于初始化varnish模块(VMODs)
vcl_fini:当所有请求都离开当前VCL,且当前VCL被弃用时,调用此函数,经常用于清理varnish模块;
四、varnish日志
为了与系统的其它部分进行交互,Child进程使用了可以通过文件系统接口进行访问的共享内存日志(shared memory log),因此,如果某线程需要记录信息,其仅需要持有一个锁,而后向共享内存中的某内存区域写入数据,再释放持有的锁即可。而为了减少竞争,每个worker线程都使用了日志数据缓存。
共享内存日志大小一般为90M,其分为两部分,前一部分为计数器,后半部分为客户端请求的数据。varnish提供了多个不同的工具如varnishlog、varnishncsa或varnishstat等来分析共享内存日志中的信息并能够以指定的方式进行显示。
五、VCL概念介绍
Varnish Configuration Language (VCL)是varnish配置缓存策略的工具,它是一种基于“域”(domain specific)的简单编程语言,它支持有限的算术运算和逻辑运算操作、允许使用正则表达式进行字符串匹配、允许用户使用set自定义变量、支持if判断语句,也有内置的函数和变量等。使用VCL编写的缓存策略通常保存至.vcl文件中,其需要编译成二进制的格式后才能由varnish调用。事实上,整个缓存策略就是由几个特定的子例程如vcl_recv、vcl_fetch等组成,它们分别在不同的位置(或时间)执行,如果没有事先为某个位置自定义子例程,varnish将会执行默认的定义。
VCL策略在启用前,会由management进程将其转换为C代码,而后再由gcc编译器将C代码编译成二进制程序。编译完成后,management负责将其连接至varnish实例,即child进程。正是由于编译工作在child进程之外完成,它避免了装载错误格式VCL的风险。因此,varnish修改配置的开销非常小,其可以同时保有几份尚在引用的旧版本配置,也能够让新的配置即刻生效。编译后的旧版本配置通常在varnish重启时才会被丢弃,如果需要手动清理,则可以使用varnishadm的vcl.discard命令完成。
六、varnish的后端存储
varnish支持多种不同类型的后端存储,这可以在varnishd启动时使用-s选项指定。后端存储的类型包括:
(1)file:使用特定的文件存储全部的缓存数据,并通过操作系统的mmap()系统调用将整个缓存文件映射至内存区域(如果条件允许);
(2)malloc:使用malloc()库调用在varnish启动时向操作系统申请指定大小的内存空间以存储缓存对象;
(3)persistent(experimental):与file的功能相同,但可以持久存储数据(即重启varnish数据时不会被清除);仍处于测试期;
varnish无法追踪某缓存对象是否存入了缓存文件,从而也就无从得知磁盘上的缓存文件是否可用,因此,file存储方法在varnish停止或重启时会清除数据。而persistent方法的出现对此有了一个弥补,但persistent仍处于测试阶段,例如目前尚无法有效处理要缓存对象总体大小超出缓存空间的情况,所以,其仅适用于有着巨大缓存空间的场景。
选择使用合适的存储方式有助于提升系统性,从经验的角度来看,建议在内存空间足以存储所有的缓存对象时使用malloc的方法,反之,file存储将有着更好的性能的表现。然而,需要注意的是,varnishd实际上使用的空间比使用-s选项指定的缓存空间更大,一般说来,其需要为每个缓存对象多使用差不多1K左右的存储空间,这意味着,对于100万个缓存对象的场景来说,其使用的缓存空间将超出指定大小1G左右。另外,为了保存数据结构等,varnish自身也会占去不小的内存空间。
为varnishd指定使用的缓存类型时,-s选项可接受的参数格式如下:
malloc[,size] 或file[,path[,size[,granularity]]] 或persistent,path,size {experimental}
file中的granularity用于设定缓存空间分配单位,默认单位是字节,所有其它的大小都会被圆整。
七、Varnish状态引擎(state engine)
VCL用于让管理员定义缓存策略,而定义好的策略将由varnish的management进程分析、转换成C代码、编译成二进制程序并连接至child进程。varnish内部有几个所谓的状态(state),在这些状态上可以附加通过VCL定义的策略以完成相应的缓存处理机制,因此VCL也经常被称作“域专用”语言或状态引擎,“域专用”指的是有些数据仅出现于特定的状态中。
1、VCL状态引擎
在VCL状态引擎中,状态之间具有相关性,但彼此间互相隔离,每个引擎使用return(x)来退出当前状态并指示varnish进入下一个状态。
varnish开始处理一个请求时,首先需要分析HTTP请求本身,比如从首部获取请求方法、验正其是否为一个合法的HTT请求等。当这些基本分析结束后就需要做出第一个决策,即varnish是否从缓存中查找请求的资源。这个决定的实现则需要由VCL来完成,简单来说,要由vcl_recv方法来完成。如果管理员没有自定义vcl_recv函数,varnish将会执行默认的vcl_recv函数。然而,即便管理员自定义了vcl_recv,但如果没有为自定义的vcl_recv函数指定其终止操作(terminating),其仍将执行默认的vcl_recv函数。事实上,varnish官方强烈建议让varnish执行默认的vcl_recv以便处理自定义vcl_recv函数中的可能出现的漏洞。
2、VCL语法
VCL的设计参考了C和Perl语言,因此,对有着C或Perl编程经验者来说,其非常易于理解。其基本语法说明如下:
(1)//、#或/* comment */用于注释
(2)sub $name 定义函数
(3)不支持循环,有内置变量
(4)使用终止语句,没有返回值
(5)域专用
(6)操作符:=(赋值)、==(等值比较)、~(模式匹配)、!(取反)、&&(逻辑与)、||(逻辑或)
VCL的函数不接受参数并且没有返回值,因此,其并非真正意义上的函数,这也限定了VCL内部的数据传递只能隐藏在HTTP首部内部进行。VCL的return语句用于将控制权从VCL状态引擎返回给Varnish,而非默认函数,这就是为什么VCL只有终止语句而没有返回值的原因。同时,对于每个“域”来说,可以定义一个或多个终止语句,以告诉Varnish下一步采取何种操作,如查询缓存或不查询缓存等。
3、VCL的内置函数
VCL提供了几个函数来实现字符串的修改,添加bans,重启VCL状态引擎以及将控制权转回Varnish等。
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参数则用于限定最大重启次数。
4、vcl_recv
vcl_recv是在Varnish完成对请求报文的解码为基本数据结构后第一个要执行的子例程,它通常有四个主要用途:
(1)修改客户端数据以减少缓存对象差异性;比如删除URL中的www.等字符;
(2)基于客户端数据选用缓存策略;比如仅缓存特定的URL请求、不缓存POST请求等;
(3)为某web应用程序执行URL重写规则;
(4)挑选合适的后端Web服务器;
可以使用下面的终止语句,即通过return()向Varnish返回的指示操作:
pass:绕过缓存,即不从缓存中查询内容或不将内容存储至缓存中;
pipe:不对客户端进行检查或做出任何操作,而是在客户端与后端服务器之间建立专用“管道”,并直接将数据在二者之间进行传送;此时,keep-alive连接中后续传送的数据也都将通过此管道进行直接传送,并不会出现在任何日志中;
lookup:在缓存中查找用户请求的对象,如果缓存中没有其请求的对象,后续操作很可能会将其请求的对象进行缓存;
error:由Varnish自己合成一个响应报文,一般是响应一个错误类信息、重定向类信息或负载均衡器返回的后端web服务器健康状态检查类信息;
vcl_recv也可以通过精巧的策略完成一定意义上的安全功能,以将某些特定的攻击扼杀于摇篮中。同时,它也可以检查出一些拼写类的错误并将其进行修正等。
Varnish默认的vcl_recv专门设计用来实现安全的缓存策略,它主要完成两种功能:
(1)仅处理可以识别的HTTP方法,并且只缓存GET和HEAD方法;
(2)不缓存任何用户特有的数据;
安全起见,一般在自定义的vcl_recv中不要使用return()终止语句,而是再由默认vcl_recv进行处理,并由其做出相应的处理决策。
下面是一个自定义的使用示例:
sub vcl_recv {
if (req.http.User-Agent ~ "iPad" ||
req.http.User-Agent ~ "iPhone" ||
req.http.User-Agent ~ "Android") {
set req.http.X-Device = "mobile";
} else {
set req.http.X-Device = "desktop";
}
}
此例中的VCL创建一个X-Device请求首部,其值可能为mobile或desktop,于是web服务器可以基于此完成不同类型的响应,以提高用户体验。
5、vcl_fetch
如前面所述,相对于vcl_recv是根据客户端的请求作出缓存决策来说,vcl_fetch则是根据服务器端的响应作出缓存决策。在任何VCL状态引擎中返回的pass操作都将由vcl_fetch进行后续处理。vcl_fetch中有许多可用的内置变量,比如最常用的用于定义某对象缓存时长的beresp.ttl变量。通过return()返回给arnish的操作指示有:
(1)deliver:缓存此对象,并将其发送给客户端(经由vcl_deliver);
(2)hit_for_pass:不缓存此对象,但可以导致后续对此对象的请求直接送达到vcl_pass进行处理;
(3)restart:重启整个VCL,并增加重启计数;超出max_restarts限定的最大重启次数后将会返回错误信息;
(4)error code [reason]:返回指定的错误代码给客户端并丢弃此请求;
默认的vcl_fetch放弃了缓存任何使用了Set-Cookie首部的响应。
八、varnish配置示例
系统环境
CentOS6.5 x86_64
varnish 172.16.1.102
web1 172.16.1.103
web2 172.16.1.104
软件包
varnish-4.0.3-1.el6.x86_64.rpm
拓扑图
1、时间同步
[root@varnish ~]# ntpdate s2c.time.edu.cn [root@web1 ~]# ntpdate s2c.time.edu.cn [root@web2 ~]# ntpdate s2c.time.edu.cn 可根据需要在每个节点上定义crontab任务 [root@varnish ~]# which ntpdate /sbin/ntpdate [root@varnish ~]# echo "*/5 * * * * /sbin/ntpdate s2c.time.edu.cn &> /dev/null" >> /var/spool/cron/root [root@varnish ~]# crontab -l */5 * * * * /sbin/ntpdate s2c.time.edu.cn &> /dev/null
2、关闭防火墙
HAproxy [root@varnish ~]# service iptables stop [root@varnish~]# chkconfig iptables off [root@varnish ~]# sed -r -i "s/^(SELINUX=).*/\1permissive/g" /etc/sysconfig/selinux [root@varnish ~]# setenforce 0 [root@varnish ~]# getenforce Permissive web1 [root@web1 ~]# service iptables stop [root@web1 ~]# chkconfig iptables off [root@web1 ~]# sed -r -i "s/^(SELINUX=).*/\1permissive/g" /etc/sysconfig/selinux [root@web1 ~]# setenforce 0 [root@web1 ~]# getenforce Permissive web2 [root@web2 ~]# service iptables stop [root@web2 ~]# chkconfig iptables off [root@web2 ~]# sed -r -i "s/^(SELINUX=).*/\1permissive/g" /etc/sysconfig/selinux [root@web2 ~]# setenforce 0 [root@web2 ~]# getenforce Permissive
3、安装varnish
[root@varnish ~]# rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-4.0.el6.rpm [root@varnish ~]# yum install -y varnish
4、编辑配置文件
[root@varnish ~]# vim /etc/sysconfig/varnish [root@varnish ~]# cat /etc/sysconfig/varnish # Configuration file for varnish # # /etc/init.d/varnish expects the variable $DAEMON_OPTS to be set from this # shell script fragment. # # Maximum number of open files (for ulimit -n) NFILES=131072 # Locked shared memory (for ulimit -l) # Default log size is 82MB + header MEMLOCK=82000 # Maximum number of threads (for ulimit -u) NPROCS="unlimited" # Maximum size of corefile (for ulimit -c). Default in Fedora is 0 # DAEMON_COREFILE_LIMIT="unlimited" # Set this to 1 to make init script reload try to switch vcl without restart. # To make this work, you need to set the following variables # explicit: VARNISH_VCL_CONF, VARNISH_ADMIN_LISTEN_ADDRESS, # VARNISH_ADMIN_LISTEN_PORT, VARNISH_SECRET_FILE, or in short, # use Alternative 3, Advanced configuration, below RELOAD_VCL=1 # This file contains 4 alternatives, please use only one. ## Alternative 1, Minimal configuration, no VCL # # Listen on port 6081, administration on localhost:6082, and forward to # content server on localhost:8080. Use a fixed-size cache file. # #DAEMON_OPTS="-a :6081 \ # -T localhost:6082 \ # -b localhost:8080 \ # -u varnish -g varnish \ # -s file,/var/lib/varnish/varnish_storage.bin,1G" ## Alternative 2, Configuration with VCL # # Listen on port 6081, administration on localhost:6082, and forward to # one content server selected by the vcl file, based on the request. Use a # fixed-size cache file. # #DAEMON_OPTS="-a :6081 \ # -T localhost:6082 \ # -f /etc/varnish/default.vcl \ # -u varnish -g varnish \ # -S /etc/varnish/secret \ # -s file,/var/lib/varnish/varnish_storage.bin,1G" ## Alternative 3, Advanced configuration # # See varnishd(1) for more information. # # # Main configuration file. You probably want to change it :) VARNISH_VCL_CONF=/etc/varnish/default.vcl # # # Default address and port to bind to # # Blank address means all IPv4 and IPv6 interfaces, otherwise specify # # a host name, an IPv4 dotted quad, or an IPv6 address in brackets. # VARNISH_LISTEN_ADDRESS= VARNISH_LISTEN_PORT=80 # 服务监听端口 # # # Telnet admin interface listen address and port VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1 VARNISH_ADMIN_LISTEN_PORT=6082 # # # Shared secret file for admin interface VARNISH_SECRET_FILE=/etc/varnish/secret # # # The minimum number of worker threads to start VARNISH_MIN_THREADS=50 # # # The Maximum number of worker threads to start VARNISH_MAX_THREADS=1000 # # # Idle timeout for worker threads VARNISH_THREAD_TIMEOUT=120 # # # Cache file size: in bytes, optionally using k / M / G / T suffix, # # or in percentage of available disk space using the % suffix. VARNISH_STORAGE_SIZE=64M # 定义缓存空间大小,这里是测试环境,所以给小一点 # # # Backend storage specification VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SIZE}" # 定义后端存储方式,varnish4.0默认为malloc # # # Default TTL used when the backend does not specify one VARNISH_TTL=120 # # # DAEMON_OPTS is used by the init script. If you add or remove options, make # # sure you update this section, too. 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} \ -p thread_pool_min=${VARNISH_MIN_THREADS} \ -p thread_pool_max=${VARNISH_MAX_THREADS} \ -p thread_pool_timeout=${VARNISH_THREAD_TIMEOUT} \ -u varnish -g varnish \ -S ${VARNISH_SECRET_FILE} \ -s ${VARNISH_STORAGE}" # ## Alternative 4, Do It Yourself. See varnishd(1) for more information. # # DAEMON_OPTS=""
5、启动服务
启动varnish服务 [root@varnish ~]# service varnish start Starting Varnish Cache: [ OK ] 查看监听端口 [root@varnish ~]# netstat -tnlp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1061/rpcbind tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1553/haproxy tcp 0 0 0.0.0.0:56177 0.0.0.0:* LISTEN 1079/rpc.statd tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1674/sshd tcp 0 0 0.0.0.0:1080 0.0.0.0:* LISTEN 1553/haproxy tcp 0 0 127.0.0.1:6082 0.0.0.0:* LISTEN 1982/varnishd tcp 0 0 :::58667 :::* LISTEN 1079/rpc.statd tcp 0 0 :::111 :::* LISTEN 1061/rpcbind tcp 0 0 :::22 :::* LISTEN 1674/sshd
6、编辑vcl文件
[root@varnish varnish]# vim test.vcl [root@varnish varnish]# cat test.vcl vcl 4.0; backend websrv1 { .host = "192.168.1.111"; .port = "80"; } sub vcl_deliver { if (obj.hits > 0) { set resp.http.X-Cache = "HIT from " + server.ip; } else { set resp.http.X-Cache = "MISS"; } }
7、连接管理端口
[root@varnish ~]# 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,-smalloc,-smalloc,-hcritbit varnish-4.0.3 revision b8c4a34 Type 'help' for command list. Type 'quit' to close CLI session. varnish> help 200 help [<command>] ping [<timestamp>] auth <response> quit banner status start stop vcl.load <configname> <filename> # 加载编译新配置,configname是配置名,filename是配置文件 vcl.inline <configname> <quoted_VCLstring> vcl.use <configname> # 使用配置,需指定配置名,当前使用的配置以最后一次vcl.use为准 vcl.discard <configname> vcl.list # 列出所有的配置 param.show [-l] [<param>] param.set <param> <value> panic.show panic.clear storage.list vcl.show [-v] <configname> backend.list [<backend_expression>] backend.set_health <backend_expression> <state> ban <field> <operator> <arg> [&& <field> <oper> <arg>]... ban.list 查看所有的vcl列表 varnish> vcl.list 200 active 0 boot 生效刚才刚才定义的vcl文件,test1为配置名,可自行定义,后面跟上自定义vcl的路径 varnish> vcl.load test1 ./test.vcl 200 VCL compiled. varnish> vcl.list 200 active 0 boot available 0 test1 变成available的状态之后就可以使用了 varnish> vcl.use test1 200 VCL 'test1' now active varnish> vcl.list 200 available 0 boot active 0 test1 在另外一台主机上使用curl命令测试缓存是否命中,可以看到第一次为MISS,第二次就是HIT了 [root@soysauce ~]# curl -I http://172.16.1.102 HTTP/1.1 200 OK Date: Fri, 22 Jan 2016 20:47:04 GMT Server: Apache/2.2.15 (CentOS) Last-Modified: Fri, 22 Jan 2016 20:40:57 GMT ETag: "c04fd-e-529f23c80f743" Content-Length: 14 Content-Type: text/html; charset=UTF-8 X-Varnish: 98315 Age: 0 Via: 1.1 varnish-v4 X-Cache: MISS Connection: keep-alive [root@soysauce ~]# curl -I http://172.16.1.102 HTTP/1.1 200 OK Date: Fri, 22 Jan 2016 20:47:04 GMT Server: Apache/2.2.15 (CentOS) Last-Modified: Fri, 22 Jan 2016 20:40:57 GMT ETag: "c04fd-e-529f23c80f743" Content-Length: 14 Content-Type: text/html; charset=UTF-8 X-Varnish: 65548 98316 Age: 4 Via: 1.1 varnish-v4 X-Cache: HIT from 172.16.1.102 Connection: keep-alive
8、禁止缓存test.html
增加如下一段subroutine vcl_recv [root@varnish varnish]# cat test.vcl vcl 4.0; backend websrv1 { .host = "192.168.1.111"; .port = "80"; } sub vcl_recv { if (req.url ~ "test.html") { return(pass); } return(hash); } sub vcl_deliver { if (obj.hits > 0) { set resp.http.X-Cache = "HIT from " + server.ip; } else { set resp.http.X-Cache = "MISS"; } } 加载并使用 varnish> vcl.load test4 ./test.vcl 200 VCL compiled. varnish> vcl.use test4 200 VCL 'test4' now active 测试是否缓存命中,可以看到无论请求多少次,都会是MISS [root@soysauce ~]# curl -I http://172.16.1.102/test.html HTTP/1.1 200 OK Date: Fri, 22 Jan 2016 21:00:07 GMT Server: Apache/2.2.15 (CentOS) Last-Modified: Fri, 22 Jan 2016 20:59:38 GMT ETag: "c04fe-a-529f27f509a82" Accept-Ranges: bytes Content-Length: 10 Content-Type: text/html; charset=UTF-8 X-Varnish: 98320 Age: 0 Via: 1.1 varnish-v4 X-Cache: MISS Connection: keep-alive [root@soysauce ~]# curl -I http://172.16.1.102/test.html HTTP/1.1 200 OK Date: Fri, 22 Jan 2016 21:00:08 GMT Server: Apache/2.2.15 (CentOS) Last-Modified: Fri, 22 Jan 2016 20:59:38 GMT ETag: "c04fe-a-529f27f509a82" Accept-Ranges: bytes Content-Length: 10 Content-Type: text/html; charset=UTF-8 X-Varnish: 65556 Age: 0 Via: 1.1 varnish-v4 X-Cache: MISS Connection: keep-alive
9、禁止缓存.php结尾的文件
增加如下一段subroutine vcl_recv [root@varnish varnish]# cat test.vcl vcl 4.0; backend websrv1 { .host = "192.168.1.111"; .port = "80"; } sub vcl_recv { if (req.url ~ "test.html") { return(pass); } return(hash); } sub vcl_recv { if (req.url ~ "\.php$") { return(pass); } } sub vcl_deliver { if (obj.hits > 0) { set resp.http.X-Cache = "HIT from " + server.ip; } else { set resp.http.X-Cache = "MISS"; } } 加载并使用 varnish> vcl.load test5 ./test.vcl 200 VCL compiled. varnish> vcl.use test5 200 VCL 'test5' now active varnish> vcl.list 200 available 0 boot available 0 test1 available 0 test2 available 0 test3 available 0 test4 active 0 test5
关于修剪缓存对象等内容后续补充