Varnish 安装与配置

介绍

Varnish是一款高性能的开源HTTP加速器,挪威最大的在线报纸Verdens Gang使用3台Varnish代替了原来的12台Squid,性能居然比以前更好。Varnish 的作者Poul-Henning Kamp是FreeBSD的内核开发者之一,他认为现在的计算机比起1975年已经复杂许多。在1975年时,储存媒介只有两种:内存与硬盘。但现在计算机系统的内存除了主存外,还包括了cpu内的L1、L2,甚至有L3快取。硬盘上也有自己的快取装置,因此Squid cache自行处理物件替换的架构不可能得知这些情况而做到最佳化,但操作系统可以得知这些情况,所以这部份的工作应该交给操作系统处理,这就是Varnish cache设计架构。目前很多互联网公司在使用Varnish,其中包括Facebook

特性

环境

OS: CentOS 5.5
varnish: 2.1.5

安装

首先安装ncurses-devel,否则varnishstatvarnishtop都无法编译完成

$ yum install ncurses-devel

接下来安装varnish

$ wget http://repo.varnish-cache.org/source/varnish-2.1.5.tar.gz
$ tar -zxvf varnish-2.1.5.tar.gz
$ cd varnish-2.1.5
$ ./configure --prefix=/usr/local/varnish-2.1.5
$ make && make install

启动

$ /usr/local/varnish2.1.5/sbin/varnishd -f \
/usr/local/varnish2.1.5/etc/varnish/default.vcl \
-T 127.0.0.1:2000 -a 0.0.0.0:80 -s file,/tmp,200M

其中-f用来指定配置文件,-T指定管理台的访问地址,-a指定Varnish监听地址,-s指定Varnish以文件方式来缓存资源,地址为/tmp,大小200MB。

配置

#后端处理器b1
backend b1{
    .host = "192.168.2.110";
    .port = "81";
    .connect_timeout = 5s;
    .first_byte_timeout= 5s;
    .probe = {
        #health check
        .url = "/check.txt";
        .interval = 5s;
        .timeout = 5s;
        .window = 5;
        .threshold = 3;
    }
}

#后端处理器b2
backend b2{
    .host = "192.168.2.109";
    .port = "81";
    .connect_timeout = 5s;
    .first_byte_timeout = 5s;
    .probe = {
        #health check
        .url = "/check.txt";
        .interval = 5s;
        .timeout = 5s;
        .window = 5;
        .threshold = 3;
    }
}

#以轮询方式实现负载均衡
director d1 round-robin {
    {
        .backend = b1;
    }

    {
        .backend = b2;
    }
}

#acl
acl purge {
    "localhost";
    "192.168.0.64";
}

sub vcl_recv {
     # 设置director
     set req.backend = d1;

     # 如果从后端返回的资源中含有Set-Cookie头的话,那么varnish不会进行缓存;
     # 如果客户端发送了Cookie头的话,那么varnish会bypass(绕开)缓存,
     # 直接发送到后端,并不会进行缓存,所以需要如下处理:
    if ( !( req.url ~ ^/admin/) ) {
        unset req.http.Cookie;
    }

    if (req.http.Cookie == "") {
        remove req.http.Cookie;
    }

    if (req.restarts == 0) {
        if (req.http.x-forwarded-for) {
            set req.http.X-Forwarded-For =
                req.http.X-Forwarded-For ", " client.ip;
        } else {
            set req.http.X-Forwarded-For = client.ip;
        }
     }

     if (req.request != "GET" &&
       req.request != "HEAD" &&
       req.request != "PUT" &&
       req.request != "POST" &&
       req.request != "TRACE" &&
       req.request != "OPTIONS" &&
       req.request != "DELETE" &&
       req.request != "PURGE") {

         /* Non-RFC2616 or CONNECT which is weird. */
         return (pipe);
     }

     # allow PURGE from localhost and 192.168.0...
     if (req.request == "PURGE") {
         if (!client.ip ~ purge) {
             error 405 "Not allowed.";
         }
         return (lookup);
     }

     if (req.request != "GET" && req.request != "HEAD" && req.request != "PURGE") {
         /* We only deal with GET and HEAD by default */
         return (pass);
     }

     if (req.http.Authorization || req.http.Cookie) {
         /* Not cacheable by default */
         return (pass);
     }
     return (lookup);
 }

sub vcl_hit {
     if (req.request == "PURGE") {
        # Note that setting ttl to 0 is magical.
        # the object is zapped from cache.
        set obj.ttl = 0s;
        error 200 "Purged.";

     } else {
        return (deliver);
     }
}

sub vcl_miss {
    if (req.request == "PURGE") {
        error 404 "Not in cache.";
    } else {
        return (fetch);
    }
}

sub vcl_fetch {
     #设置TTL为1个小时
     set beresp.ttl = 1h;
     if (!beresp.cacheable) {
         return (pass);
     }

     if (beresp.http.Set-Cookie) {
         return (pass);
     }

     return (deliver);
 }

sub vcl_deliver {
     return (deliver);
}

启动脚本

$ wget -O varnishd https://raw.github.com/gist/3671408/3a51578bbd60a4cf8317bdc9508527b81eb23da5/varnishd
$ cp varnishd /etc/init.d/varnishd
$ chmod +x /etc/init.d/varnishd
$ /etc/init.d/varnishd start

Subroutine列表

重要变量

subroutine不带参数,一般通过全局变量来实现信息的传递。

如下变量在backend中有效:

如下变量在处理一个请求(例如vcl_recv)的时候可用:

如下变量在准备一个后端请求(比如在cache miss或者passpipe模式)的时候可用:

如下的变量在请求对象从后端返回之后,在其被放入缓存之前可用。换句话说,也就是在vcl_fetch中可用。

在对象已经存在于缓存中并被查询到的时候,一般在vcl_hitvcl_deliver中,如下的变量(大部分是read-only)可用:

如下变量在决定对象hash key的时候可用:

如下变量在准备把一个响应发送给客户端时候可用:

(完)
comments powered by Disqus
Powered by GitHub  &&  Jekyll | CC BY-NC-SA