varnish的Backend storage的管理

    varnish缓存服务器是工做在代理模式的。意思是说,由varnish接收用户的请求,把用户请求资源的URL作“哈唏”编码后,作为“键”与缓存条目中的键作比对:html

    一、若是,缓存条目有如出一辙的键的话,那么该键对应的值就是用户请求URL对应的资源,vim

       varnish把该键对应的值取出来,响应给客户端。后端

    二、若是,缓存条目没有与之匹配的键的话,那么varnish 就向后端服务器(backup server)发送缓存

       请求。当后端服务器(backup server )构建完响应报文响应varnish,varnish服务器收到后端安全

       服务器(backup server)的响应后,会把:用户请求的URL作“哈唏”编码后,bash

       做为键(key),该URL对应的资源做为值(value),保存在varnish的缓存中。服务器

       这就是所谓的,插入缓存条目。 varnish的缓存条目是:key:value 方式存在的。curl

       而后,varnish再构建响应报文响应客户端。tcp

这就是,varnish 缓存服务器的正常工做流程。ide

以下图所示:

wKioL1QkITWRXjylAALLTNOHn-Y023.jpg

那么如何实现varnish缓存的管理呢?

一、varnish接收用户请求后,是如何根据用户请求的报文来决定是否查找缓存的呢?

   由上图所知。当 varnish 服务器接收到用户请求后,分析用户请求的 URL 是否符合缓存标准,再查找缓存。这样是为了不花费在与缓存条目比对的时间。若是,缓存条目较多的话,作缓存比对也是须要很长时间的。varnish经过以下方式,控制那些URL能够查找缓存的:

    varnish 在vcl_recv状态引擎定义策略,怎么样处理用户的请求的。如:varnish 处理的客户端请求的标准、若是判断是否查找缓存的。

sub vcl_recv {
    # varnish 在vcl_recv状态引擎定义的策略来控制,varnish服务器只处理指定http协议请求资源的方法,的URL
   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);  -----> 用户请求的访问的服务虽然是:tcp/80 可是,varnish不处理除了,GET、HEAD、PUT、POST、TRACE、OPTIONS、DELETE请求资源的方法。直接让该请求把该请求交给backup server.
    }

    # 再使用下述策略来过滤用户请求资源时所使用的方法;判断用户请求资源时使用的方法不是:GET、HEAD 就绕过查找缓存的操做
    if (req.request != "GET" && req.request != "HEAD") {
        /* We only deal with GET and HEAD by default */
        return (pass);  -----> 绕过查找缓存操做,varnish直接向 backup server 请求资源
    }
    # 使用vcl_recv状态引擎判断用户的请求,都不符合上述:if 条件。那么该用户请求资源所使用的方法必定是:GET或HEAD。可是若是用户访问的是资源,须要经过口令认证
    # 才能够访问的。用户请求该资源使用的也是"GET"方法。该用户请求的URL是不须要查找缓存的。
    if (req.http.Authorization || req.http.Cookie) {
       /* Not cacheable by default */
        return (pass);   -----> 绕过查找缓存操做,varnish直接向 backup server 请求资源
    }

    return (lookup);  ------> 查找缓存
}

说明:

    varnish 有不少内置变量保存了,http协议报文的信息。经过使用if判断这些信息,来控制varnish是如何使用缓存的。

    如:

req.url            ------> 记录用户请求的URL
req.request        -------> 记录了用户请求资源使用的方法
req.http.HEADER    -------> 记录了用户请求报文的首部。该变量是可写的。如:req.http.hostreq.restarts          ------->  请求被重启的次数
server.ip             -------> varnish 的IP地址
server.port           -------> varnish 监听的端口
server.hostname       -------> 服务器的主机名
client.ip             -------> 客户端IP
req.backend           -------> 若是,未从缓存中命中。该请求分调度到后端的那个服务器。

例:

   当用户访问指定页面时,禁止查询缓存

     sub vcl_recv {
	    ...
	    if (req.url ~ "/p_w_picpaths/a.jpg$" ) {
	        return (pass);
	    }

	    return (lookup);
	}

二、当缓存没有命中(cache miss)如何控制 varnish 向缓存中插入缓存条目时,该缓存条目的过时时长呢?

使用 varnish  缓存服务器提供的:vcl_fetch 状态引擎来控制是否向缓存中插入缓存条目的。

如:

sub vcl_recv {
      ....
           if (req.request == "GET" && req.request ~ "\.png$") {
          set beresp.ttl = 10s;
      }
      ....
}

三、如何修剪(删除)缓存条目呢?

使用 varnish 提供 purge指令来清除不须要的缓存

如:

(1)、为了安全,对操做清除缓存条目的指令的用户作限制

只容许下述用户修剪缓存条目

   acl purgers {
   "127.0.0.1";
   "172.16.13.0"/24;
}

(2)、在vcl_recv 状态引擎,放行purge请求方法查询缓存

sub vcl_recv {
。。。
 if (req.request == "PURGE") { ----------> 开放用户请求资源使用 purgers 方法,
     if ( client.ip !~ purgers ) {  ------> 检测发起 PURGE 方法的用户来源,只容许属于purgers的用户的请求查询缓存
           error 405 "Method not allowed";
      }
          return (lookup);  --------> 查询缓存
  }

}

(3)、当缓存命中(cache hit)就执行varnish 的purge清除(修剪)缓存条目的指令

sub vcl_hit {
     if (req.request == "PURGE") {
        purge; ----------> 执行varnish 修改缓存的指令
        error 200 "Purged";   ----> 合成状态码,和“缘由短语”
     } 
     return (deliver);
 }

(4)、使用【curl】指定使用PURGE方法访问指定的资源,实现缓存修剪

如:

curl -X PURGE http://172.16.13.1/index.html

说明:

 

四、定义缓存大小; 

[root@haproxy2 ~]# vim /etc/sysconfig/varnish
VARNISH_STORAGE_SIZE=64M  ----> 定义缓存大小
VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SIZE}" ---> 明确指定varnish使用内存作为缓存。
相关文章
相关标签/搜索