主页 > Drupal | 服务器技术 > 用Varnish加速动态页面-对PHP/Drupal的页面缓存

用Varnish加速动态页面-对PHP/Drupal的页面缓存

PDF版本

varnish的基本介绍就不在此赘述,关于使用varnish缓存,之前也有几篇文件进行介绍,不过大部分情况下,我们使用varnish限于两个方面,其一是用varnish做反向代理,另一个用途就是用它来缓存静态内容,比如图片、css、js文件等。既然varnish可以缓存任何http请求,那么本文就varnish关于动态页面的缓存做一些测试和应用,文中举例基于drupal系统,也可以应用基于PHP的其他系统。

对于Varnish的基本概念,请参考之前的两篇文章:
高负载网站之Varnish与Drupal – 基本篇
Varnish构建高负载Drupal网站 – 高级篇

首先了解几个概念,

1. Varnish不缓存带有Set-Cookie头的http输出。
2. 对于HTTP协议中缓存部分,Varnish遵从http协议部分。如:带有如下头信息,Control-Cache: no-store, no-cache, must-revalidate, post-check=0, pre-check=0,默认varnish不会缓存。
3. HTTP协议中缓存部分,Control-Cache优先于Expires,Pragma: no-cache 是HTTP1.0的产物,可以不考虑。

Varnish缓存操作,一般有两个方法,
1. 在varnish的配置文件设置。
2. 通过http协议指定,比如Control-Cache。

第一种方法耦合性较低,只需修改vcl即可,但是灵活性较差,如果要独立设置每个页面的ttl可能比较麻烦。
第二种方法较为灵活,可以设置每一个页面的缓存时间,比如Control-Cache: max-age=10. (缓存10秒),缺点就是耦合性,既要在PHP端设置,又要在Varnish里面设置。

小插曲:如果使用Control-Cache: max-age=10这种方式缓存的话,varnish可以缓存,但是会出现一个问题,客户端的浏览器同样会缓存,如果不让客户端浏览器缓存,而只让varnish缓存,可以使用 Control-Cache: max-age=0; s-maxage:10.

这里,我们选择使用VCL,也就是上面所说的第一种方法来缓存http动态页面。
如下假设:
a) 要缓存的页面url为 /abc/* 的形式,
b) 只缓存匿名用户的页面(登录用户以后再介绍)
c) 登录用户需要有一个独有的cookie,如DRUPAL_UID=11

1. 在vcl_recv里面添加如下代码(此处,一定要将登录用户的请求pass到后端服务器,否则,也会得到缓存页面,因为varnish的hash默认没有cookie,所以登录用户同样会命中匿名用户的缓存数据)。

 if (req.request == "GET" && req.url ~ "^/abc/.*") {
    if (req.http.Cookie ~ "DRUPAL_UID=[1-9][0-9]*") {
      return (pass);
    } else {
      remove req.http.Cookie;
      return (lookup);
    }
 }

2. 在vcl_fetch里面添加如下代码

if (req.request == "GET" && req.http.Cookie !~ "DRUPAL_UID=[1-9][0-9]*" && req.url ~ "^/abc/.*") {
    unset beresp.http.Pragma;
    unset beresp.http.Expires;
    unset beresp.http.set-cookie;
    set beresp.ttl = 2h; #time to live
    set beresp.do_gzip = true;
    set beresp.grace = 20m; #grace time
    return (deliver);
  }

在vcl_fetch里面注意,最好把set-cookie unset掉,这样就不会修改客户端的cookie了(一般情况,varnish向后台用户发送的是匿名请求,这样set-cookie肯定是一个匿名的session信息,如果当前用户是登录用户,就会导致当前用户logout,这点特别注意)。

这样,就在varnish里面强制缓存了所有/abc/开始的页面内容,缓存时间为2小时。

最后补充一个vcl的调试技巧,在varnish3.x里面引入了std模块,varnish vmod_std包含了一些常用函数,所以调试vcl的时候,我们可以使用std.syslog(1, xxx)等语句,将某个变量记录到syslog里面(/var/log/messages),方便观察结果。

在Varnish的设置中,理解其处理http请求的过程非常重要,因此,这里贴一张VCL的流程图,以便更好的理解varnish处理的过程。

varnish flow

varnish 处理http的流程

后记:关于登录用户页面的缓存,下一篇再做讨论。Varnish的负载均衡配置,可以参考这篇文章《Varnish前端代理Drupal的配置以及Jenkins》。


声明: 本站所有文章欢迎转载,所有文章未说明,均属于原创,转载均请注明出处。
本文有效链接: http://www.drupal001.com/2013/05/varnish-cache-php-output/
版权所有: Drupal与高性能网站架构 http://www.drupal001.com


, ,

评论:2

发表评论
  1. avatar
    回复 sens
    13/07/23

    博主,在fetch中确实缓存了页面,但是第二次用户请求过来再recv中还会走pass,这样就起不到缓存的效果,不知道你测试结果如何。

    • avatar
      回复 robbin
      13/08/01

      你看看你的http里面的vary变量,如果把其他不用的去掉,比如user-agent

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注


+ 8 = 十三

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

引用:1

下面所列的是引用到本博客的链接
用Varnish加速动态页面-对PHP/Drupal的页面缓存 来自 Drupal与高性能网站架构
pingback 来自 研究Varnish | Tinyfool的Blog 2014 年 1 月 21 日

[…] 用Varnish加速动态页面-对PHP/Drupal的页面缓存 […]

顶部