varnish简介

    Varnish是一个轻量级的Cache和反向代理软件,先进的设计理念和成熟的设计框架是Varnish的主要特点,现在的Varnish总共代码量不大,功能上虽然在不断改进,但是还需要继续丰富和加强。下面总结了Varnish的一些特点:
1)是基于内存缓存,重启后数据将消失。
2)利用虚拟内存方式,io性能好。
3)支持设置0~60秒内的精确缓存时间。
4VCL配置管理比较灵活。
532位机器上缓存文件大小为最大2G
6)具有强大的管理功能,例如topstatadminlist等。
7)状态机设计巧妙,结构清晰。
8)利用二叉堆管理缓存文件,达到积极删除目的。


    


varnish的工作原理

varnish之基础篇_缓存


varnish的存储方式

    varnish有三种有存储方式:

        1、file:存储在磁盘空间,但是在varnish重启后会被清除;其通过mmap()系统调用将缓存文件映射到内存空间

        2、malloc:存储在内存空间,其通过malloc()库调用在varnish启动时申请置顶大小的内存空间用于存储缓存对象

        3、persistent:与file一样,但是可以永久存储缓存文件,但其现处于测试阶段

        

选定存储方式:

1、在varnished启动时使用-s选项指定:

malloc [,size]

file [,path[,size[,granularity]]]

persistent,path,size {experimental}

2、在配置文件中修改:

#vim /etc/sysconfig/varnish

varnish之基础篇_工作流程_02


varnish的状态引擎

         VCL用于让管理员定义缓存策略,而定义好的策略将由varnish的management进程分析、转换成代码、编译成二进制程序并连接至child进程。varnish内部有几个所谓的状态(state),在这些状态上可以附加通过VCL定义的策略以完成相应的缓存处理机制,因此VCL也经常被称作“域专用”语言或状态引擎,“域专用”指的是有些数据仅出现于特定的状态中。

vcl_recv:用于接受和处理请求,成功接受到后根据数据来决定如何处理请求:

vcl_pipe:将请求直接爨地至后端主机,在请求和返回内容没有改变的前提下将不变的内容返回给客户端

vcl-pass:将请求发送给后端主机,且后端主机返回的数据不缓存,直接传送给用户

vcl_hash:在hash表中查找缓存的对象产生hit或miss两种状态

vcl_hit:请求的数据命中后会执行两种情况:1)丢弃,重新向后端主机发起请求;2)将结果执行deliver

vcl_miss:在该状态有两种方式进行fetch,一种是以pass执行,获取结果不缓存;一种是直接执行fetch,获取的结果缓存

vcl_fetch:从主机更新缓存并且获取内容,通过获取的内容来判断是否缓存

vcl_deliver:将获取的数据传送给客户端

vcl_tiomeout:此函数在缓存内容到期后使用

vcl_discard:在缓存内容到期或空间不足时调用


在完整的请求处理流程中会有如下集中模式:pipe、looku、pass、deliver

或者是直接向用户返回error code [reason]  :返回code给客户端,并放弃处理该请求

varnish之基础篇_状态引擎_03

处理http请求的有一下几个关键性步骤:

receive状态:处理请求的路口状态,通过vcl规则判断是将请求pass还是pipe、或者进入lookup状态查询本地缓存

lookup状态:在hash表中查找数据,命中进入hit状态,未命中进入miss状态

fetch状态:对后端发起请求,获得数据;的到出局后可以选择在本地缓存后执行deliver或者直接执行deliver

deliver状态:将获取到的数据发送给客户端,完成本次请求



varnish的Director支持的算法

    round-roubin:这种类型没有参数,只需要为其指定后端主机即可,就能活后端的主机进行轮询,当主机故障时则不在挑选

    random:随机从后端主机中进行挑选,每个主机狗需要指定一个.weight参数,同时还可以使用.reties为direcotr级别设定查找健康后端的尝试次数

//在2.1.0后



vcl的部分变量

 当请求到达后可以使用的vcl内置的功用变量

变量名称含义
req.backend制定对应的后端主机
server.ip表示服务器端的IP
client.ip表示客户端的IP
req.request制定请求的类型,如GET,GEAD,PUT
req.url指定请求的地址
req.proto表示客户端请求的HTTP版本

req.http.header

表示对应请求中的HTTP头部信息
req.restarts表示请求重启的次数,默认最大值为4
varnish向后端主机请求时使用的变量:

变量名称含义
beresp.request指定请求的类型,如GET、HEAD等
beresp.url指定请求的地址
beresp.proto表示向客户端发起请求的HTTP版本
beresp.http.header表示对应请求中的首部信息
beresp.ttl表示缓存的生存周期,单位是秒

从cache或后端主机获取到内容后使用的变量

obj.status表示返回内容的请求状态码,如200、504等
obj.cachetable表示返回的内容是否可以缓存,由HTTP返回的状态码且生存周期不为零,则可以缓存
obj.valid表示是否是有效的HTTP应答
obj.response

返回内容的请求状态信息

obj.proto返回内容的HTTP协议版本
obj.ttl


返回内容的缓存时间,单位秒

obj.lasture表示上一次请求到现在的间隔时间,单位秒

对客户端应答是使用的变量

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

resp.proto

...协议版本
resp.http.header...头部信息
resp.response...状态信息



与缓存的HTTP首部

cache-control

对缓存进行控制,如一个请求希望响应返回的内容在客户端要被缓存一年,或不希望被缓存就可以通过这个报文头达到目的。 

  max-age:(只接受 Age 值小于 max-age 值,并且没有过期的对象)

  max-stale:(可以接受过去的对象,但是过期时间必须小于 max-stale 值)

  min-fresh:(接受其新鲜生命期大于其当前 Age 跟 min-fresh 值之和的缓存对象)

  响应:public(可以用 Cached 内容回应任何用户)

  private(只能用缓存内容回应先前请求该内容的那个用户)

  no-cache(可以缓存,但是只有在跟WEB服务器验证了其有效后,才能返回给客户端)

  max-age:(本响应包含的对象的过期时间)

  ALL: no-store(不允许缓存)

  


Vary: WEB服务器用该头部的内容告诉 Cache 服务器,在什么条件下才能用本响应所返回的对象响应后续的请求。假如源WEB服务器在接到第一个请求消息时,其响应消息的头部为:Content- Encoding: gzip; Vary: Content-Encoding那么 Cache 服务器会分析后续请求消息的头部,检查其 Accept-Encoding,是否跟先前响应的 Vary 头部值一致,即是否使用相同的内容编码方法,这样就可以防止 Cache 服务器用自己 Cache 里面压缩后的实体响应给不具备解压能力的浏览器。

        例如:Vary:Accept-Encoding 

Via: 列出从客户端到 OCS 或者相反方向的响应经过了哪些代理服务器,他们用什么协议(和版本)发送的请求。当客户端请求到达第一个代理服务器时,该服务器会在自己发出的请求里面添 加 Via 头部,并填上自己的相关信息,当下一个代理服务器收到第一个代理服务器的请求时,会在自己发出的请求里面复制前一个代理服务器的请求的Via 头部,并把自己的相关信息加到后面,以此类推,当 OCS 收到最后一个代理服务器的请求时,检查 Via 头部,就知道该请求所经过的路由。

        例如:Via:1.0 236.D0707195.sina.com.cn:80 (squid/2.6.STABLE13) 

ETag:就是一个对象(比如URL)的标志值,就一个对象而言,比如一个 html 文件,如果被修改了,其 Etag 也会别修改,所以ETag 的作用跟 Last-Modified 的作用差不多,主要供 WEB 服务器判断一个对象是否改变了。比如前一次请求某个 html 文件时,获得了其 ETag,当这次又请求这个文件时,浏览器就会把先前获得的 ETag 值发送给WEB 服务器,然后 WEB 服务器会把这个 ETag 跟该文件的当前 ETag 进行对比,然后就知道这个文件有没有改变了。 

Expired:WEB服务器表明该实体将在什么时候过期,对于过期了的对象,只有在跟WEB服务器验证了其有效性后,才能用来响应客户请求。是 HTTP/1.0 的头部。例如:Expires:Sat, 23 May 2009 10:02:12 GMT 

Host:客户端指定自己想访问的WEB服务器的域名/IP 地址和端口号。例如:Host:rss.sina.com.cn 

If-Match:如果对象的 ETag 没有改变,其实也就意味著对象没有改变,才执行请求的动作。 

If-None-Match:如果对象的 ETag 改变了,其实也就意味著对象也改变了,才执行请求的动作。 

If-Modified-Since:如果请求的对象在该头部指定的时间之后修改了,才执行请求的动作(比如返回对象),否则返回代码304,告诉浏览器 该对象没有修改。

        例如:If-Modified-Since:Thu, 10 Apr 2008 09:14:42 GMT 

If-Unmodified-Since:如果请求的对象在该头部指定的时间之后没修改过,才执行请求的动作(比如返回对象)。 

If-Range:浏览器告诉 WEB 服务器,如果我请求的对象没有改变,就把我缺少的部分给我,如果对象改变了,就把整个对象给我。浏览器通过发送请求对象的 ETag 或者 自己所知道的最后修改时间给 WEB 服务器,让其判断对象是否改变了。总是跟 Range 头部一起使用。 

Last-Modified:WEB 服务器认为对象的最后修改时间,比如文件的最后修改时间,动态页面的最后产生时间等等。

        例如:Last-Modified:Tue, 06 May 2008 02:42:43 GMT 

Pragma:主要使用 Pragma: no-cache,相当于 Cache-Control: no-cache。

        例如:Pragma:no-cache 

Proxy-Authenticate: 代理服务器响应浏览器,要求其提供代理身份验证信息。

         Proxy-Authorization:浏览器响应代理服务器的身份验证请求,提供自己的身份信息。 


实战验证:

1、下载yum包:http://repo.varnish-cache.org

varnish之基础篇_工作流程_04

2、使用yum安装

#yum install ./*.rpm

3、修改配置文件(后端Server-IP:172.16.1.20)

#vim /etc/varnish/default.vcl

修改.host 的ip地址为172.16.1.20

#vim /etc/sysconfig/varnish

修改监听端口:

VARNISH_LISTEN_PORT=80

选定存储方式:VARNISH_STORAGE

设置存储空间:VARNISH_STORAGE_SIZE


4、启动服务,使用ss -tnlp查看80端口是否处于坚挺状态,启动后端Server


############################################################333

启动后如何修改vcl

运行过程中如何修改配置文件:

1、进入交互界面

#varnishadm -s .....  -t  127.0.0.1:6082

2、编译被我们修改后的配置文件

varnish〉vcl.load   NAME   Change_Name

Change_Name:表示我们需要编译的文件的文件名

NAME:表示编译过后叫什么名字  

3、查看编译后的vcl

varnish〉vcl.list

4、切换到我们要用到的那个vcl

varnish〉vcl.use