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
Fork me on GitHub