• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
百分百
http://www.qrw100.com
博客园    首页    新随笔    联系   管理    订阅  订阅

varnish学习测试文档

varnish 简介
下载、安装、及官方文档
配置
启动
清除缓存 

一.varnish 简介

来自百科的介绍。

二.下载、安装、及官方文档

下载页面 ,本文按3.0.0测试

安装(可以通过--prefix指定安装目录(必须是存在的目录),测试中安装目录为/webser/varnish)。PS:若已安装 pcre 包,依然报错 no package 'libpcre' found,解决办法(文中pkgconfig的路径需要自己确定)
默认安装pcre程序后,键入 export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

官方文档(3.x版——没有分清2.x、3.x,错误百出的蛋疼文档)。

三.配置

不同于apache mysql等的键值对配置,varnish的配置采用VCL(Varnish Configuration Language——varnish专用语言,其语法请参考 VCL拔高版,VCL入门版)。下面简要说明VCL语法。

1.后端声明(Backend declarations):varnish缓存内容的来源我们称之后端(backend),backend 命令用于定义后端连接参数(更多更全参考 VCL中的变量),语法如下:

//定义名为www、kankan的两个后端
backend www {
  .host = "www.example.com";
  .port = "80";
  .connect_timeout = 1s;
  .first_byte_timeout = 5s;
  .between_bytes_timeout = 2s;
}
backend kankan{
  .host = "kankan.example.com";
  .port = "80";
  .connect_timeout = 1s;
  .first_byte_timeout = 5s;
  .between_bytes_timeout = 2s;
}

 

 2.子程序(subroutines)其语法如下:

//定义名为 pipe_if_local 的子程序,可以通过 call pipe_if_local; 调用子程序。
sub pipe_if_local {
  if (client.ip ~ local) {
    return (pipe);
  }
}

 

varnish中有一些特殊的系统子程序,在处理用户请求的不同阶段被调用执行(回调),如:vcl_hit 在命中缓存时执行,vcl_recv在收到HTTP请求时执行。。。 若系统子程序不是被 return (action); 结束,将执行默认动作(默认动作的具体操作可以在 varnishRoot/etc/varnish/default.vcl 中看到 )。下面介绍常用系统子程序(更多更全参考 子程序):

vcl_recv 在完成请求的接收和解析后被调用。可以在此子程序内决定是否为此次请求服务,如何服务,指定HTTP请求使用哪个后端,清除cookies(带有cookie设置头信息的响应,varnish不会缓存其内容,带有cookies头信息的请求 varnish直接进入pass模式,更多更全更详细参考Cookies);

vcl_fetch 从后端成功获取内容后被调用;

vcl_pipe 在进入pipe模式后被调用。在pipe模式下,请求传递给后端,后端的数据直接返回给客户端,且varnish再也不过问基于当前连接的数据传输。pipe模式操作对象是当前连接,是varnish对当前连接不管不顾的表态;

vcl_pass 在进入pass模式后被调用。在pass模式下,请求传递给后端,后端的数据直接返回给客户端,但下个请求的处理流程得重新来过(即便下个请求基于当前连接)。pass模式操作对象是当前请求,是varnish对当前请求不管不顾的表态。

3.action return (action); 可以终止子程序。action可以是deliver、error、fetch、hash、lookup、pass、pipe、restart,其中error 语法格式稍有不同:error code [reason]。

4.ACLs ACL声明可以创建访问控制列表,一般用作客户端地址的匹配源。其语法如下:

//ACL名为abc
acl abc {
  "localhost";         // myself
  ! "192.0.2.23";      // except for the dialin router
}

//若客户端ip在abc中,进入pipe模式
if (client.ip ~ abc) {
  return (pipe);
}

 

 下面是当前视频站点反向代理配置

//vi /webser/varnish/vcl.conf
//定义kankan 和 webg两个后端
backend kankan { 
       .host = "117.79.224.142";
       .port = "8080";
       .connect_timeout = 10s;
       .first_byte_timeout = 10s;
       .between_bytes_timeout = 10s;
}
backend webg { 
       .host = "117.79.224.142"; 
       .port = "8089";
       .connect_timeout = 10s;
       .first_byte_timeout = 10s;
       .between_bytes_timeout = 10s; 
}
//名为purge的ACLs 允许localhost、127.0.0.1、117.79.224.142 通过PURGE方法清除缓存
acl purge {
        "localhost";
	"127.0.0.1";
        "117.79.224.142";
}

//响应头信息中加入X-Cache标识是否命中缓存
sub vcl_deliver {
	if (obj.hits > 0) {
		set resp.http.X-Cache = "HIT";
	} else {
		set resp.http.X-Cache = "MISS";
	}
}

sub vcl_recv {
	//若是PURGE 
	if (req.request == "PURGE") {
		//若客户端IP不在purge列表中
		if (!client.ip ~ purge) {
                        error 405 "Not allowed.";
                }
		
		//清除所有缓存内容
		ban("req.http.host == " + req.http.host);		
		//给出状态信息 200
		error 200 "PURGE Successed";
        }

	//删除请求中的cookie
	unset req.http.cookie;

	//若请求域名为webg.stnts.com
	if (req.http.host ~ "^webg.stnts.com") {
		//设置后端为webg
		set req.backend = webg;
	}
	else if (req.http.host ~ "^kankan.stnts.com") {
		set req.backend = kankan;
	}
	else if (req.http.host ~ "^www.58kankan.cn") {
		set req.backend = kankan;
	} else if (req.http.host ~ "^58kankan.cn") {
		set req.backend = kankan;
	}else {
		error 404 "EYoo Cache Server";
		return(lookup);
	}

	//若不是GET 也不是 POST请求 进入pipe模式
	if (req.request != "GET" && req.request != "HEAD") {
		return(pipe);
	}
	else {
		//在缓存中查找
		return(lookup);
       }
}

sub vcl_miss {
        if (req.request == "PURGE") {
                error 404 "admin"; 
        }
}

 四.启动

以root身份运行:

view source
print?
1 mkdir -p /var/vcache
2 /webser/varnish/sbin/varnishd -f /webser/varnish/vcl.conf -s file,/var/vcache/varnish_cache.data,1G -w 1000,2000,5 -T 127.0.0.1:2000

-f 指定配置文件路径。

-s 缓存的存储类型和存储容量。
-s malloc; malloc类型 -s file  [default: use /tmp]
-s file,<dir_or_file>
-s file,<dir_or_file>,<size>
-s persist{experimenta}
-s file,<dir_or_file>,<size>,<granularity>

-T 127.0.0.1:2000 开启基于文本的管理接口,可以在不停止varnish的情况下来管理varnish。推荐只监听本机对管理接口的访问。

-a 0.0.0.0:8080 制定监听所有IP发给8080端口的http请求,如果在生产环境下,应该让varnish监听80,这是默认端口。

-w int[,int[,int]] 工作者线程数
-w
-w min,max
-w min,max,timeout [default: -w2,500,300]
 

-P file 指定Pid 文件。

-t int 指定缓存TTL,单位s。默认为120 。VCL的TTL可以覆盖此配置。

五. 缓存清除

分两步:

1.子程序vcl_recv 中加入如下代码:

//若是PURGE 
if (req.request == "PURGE") {
	//若客户端IP不在purge列表中
	if (!client.ip ~ purge) {
		error 405 "Not allowed.";
	}
	
	//清除所有缓存内容
	ban("req.http.host == " + req.http.host);		
	//给出状态信息 200
	error 200 "PURGE Successed";
}

 

2.调用下面的函数

/**
 * 清除varnish缓存
 * @param string $domain 网站域名(eg:www.baidu.com)
 * @param boolean $debug 是否输出清除缓存结果信息
 * @param array $sockIpArr varnish服务器地址及端口(端口默认为80)
 */
function purge($domain, $debug = false, $sockIpArr = array())
{
	if (empty($sockIpArr) || !is_array($sockIpArr)) {
		$sockIpArr = array(
			array('ip' => '119.97.137.142'),
			array('ip' => '117.79.224.42'),
			array('ip' => '218.60.11.91'),
		);
	}

	$result = array();

	foreach ($sockIpArr as $v) {
		$sockIp = $v['ip'];
		$sockPort = empty($v['port'])?80:intval($v['port']);

		$fp = fsockopen($sockIp, $sockPort, $errno, $errstr, 30);

		if (!$fp) {
			$result[$sockIp] = false;
			continue;
		}

		$out = "PURGE / HTTP/1.1rn";
		$out .= "Host: $domainrn";
		$out .= "Connection: Closernrn";

		fwrite($fp, $out);

		if (!feof($fp)) {

			if ($debug) {
				while (!feof($fp)) {
					echo fgets($fp, 128);
				}
			}

			$result[$sockIp] = true;

		} else $result[$sockIp] = false;

		fclose($fp);
	}
	return $result;
}

 

posted @ 2012-01-11 09:27  爱尚美  阅读(616)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3