Varnish 3.x 安装配置调优及理论知识

喜夏-厌秋 提交于 2020-04-06 22:03:44

Varnish是一款高性能的开源HTTP加速器,挪威最大的在线报纸 Verdens Gang (http://www.vg.no) 使用3台Varnish代替了原来的12台squid,性能居然比以前更好。

Varnish 的作者Poul-Henning Kamp是FreeBSD的内核开发者之一,他认为现在的计算机比起1975年已经复杂许多。在1975年时,储存媒介只有两种:内存与硬盘。但现在计算 机系统的内存除了主存外,还包括了cpu内的L1、L2,甚至有L3快取。硬盘上也有自己的快取装置,因此squid cache自行处理物件替换的架构不可能得知这些情况而做到最佳化,但操作系统可以得知这些情况,所以这部份的工作应该交给操作系统处理,这就是 Varnish cache设计架构。

具体安装方法

安装 CentOS 5.x 的Varnish RPM仓库

rpm --nosignature -i http://repo.varnish-cache.org/redhat/varnish-3.0/el5/noarch/varnish-release/varnish-release-3.0-1.el5.centos.noarch.rpm

安装 CentOS 6.x 的Varnish RPM仓库

rpm --nosignature -i http://repo.varnish-cache.org/redhat/varnish-3.0/el6/noarch/varnish-release/varnish-release-3.0-1.el6.noarch.rpm

然后执行安装完毕

yum install varnish

修改启动参数:

vim /etc/sysconfig/varnish

默认HTTP端口:6081

默认管理端口:6082

默认缓存模式为file:file,/var/lib/varnish/varnish_storage.bin,1G

共三种模式file, malloc, persistent

(1)file:使用特定的文件存储全部的缓存数据,并通过操作系统的mmap()系统调用将整个缓存文件映射至内存区域(如果条件允许);

(2)malloc:使用malloc()库调用在varnish启动时向操作系统申请指定大小的内存空间以存储缓存对象;

(3)persistent(experimental):与file的功能相同,但可以持久存储数据(即重启varnish数据时不会被清除);仍处于测试期;

修改varnish配置文件

vim /etc/varnish/default.vcl

VCL配置

############定义健康状态检测###############
probe healthcheck {
.url = "/";			#定义健康检查的页面
.interval = 6s;		#探测请求的发送周期,默认为5秒;
.timeout = 1s;	#每次探测请求的过期时长
.window = 8;		#设定在判定后端主机健康状态时基于最近多少次的探测进行
.threshold = 3;		#在.window中指定的次数中,至少有多少次是成功的才判定后端主机正健康运行
.initial = 3;		#Varnish启动时对后端主机至少需要多少次的成功探测,默认同.threshold
}

############## app 服务器组及集群策略 ################
backend app01 {
.host = "192.168.0.5";
.port = "80";
.probe = healthcheck; #健康状态检测
}

backend app02 {
.host = "192.168.0.6";
.port = "80";
.probe = healthcheck; #健康状态检测
}


# 定义集群,调用服务器
director app random {	#定义一个名为webserver的directory,由app01,app02,使用random算法,处理静态请求
	{.backend = app01;.weight = 5;}	#设置权重为
	{.backend = app02;.weight = 5;}
}

############## img 服务器 ################

backend img {
.host = "192.168.0.1";
.port = "80";
}

#######################################

#purge的acl规则
acl purge {
	"localhost";
	"127.0.0.1";
}

#vcl_recv函数段
sub vcl_recv
{
	# varnish内部有一个grace模式。当后端不可用,或者已经向后端发过更新请求的情况下,别的客户再请求这个对象时,会收到已经过期的版本,当然过期的时间在可接受的范围内。
	# 在收到用户请求时指定可以接受过期对象的过期时间范围

	if (!req.backend.healthy) {
		set req.grace = 5m;
	} else {
		set req.grace = 15s;
	}

	#定义清除缓存IP,调用上面的Acl
	if (req.request == "PURGE") { #使用PURGE命令清除缓存
		if (!client.ip ~ purge) { #非ACl定义的IP,则不能清除缓存
			error 405 "Not allowed.";
		}
		return (lookup);
	}

	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") {
		/* Non-RFC2616 or CONNECT which is weird. */
		return (pipe);
	}

	# 对图片及压缩文件的 Accept-Encoding 统一化 提高命中率
	if (req.http.Accept-Encoding) {
		if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
			# No point in compressing these
			unset req.http.Accept-Encoding;
		} elsif (req.http.Accept-Encoding ~ "gzip") {
			set req.http.Accept-Encoding = "gzip";
		} elsif (req.http.Accept-Encoding ~ "deflate") {
			set req.http.Accept-Encoding = "deflate";
		} else {
			# unknown algorithm
			unset req.http.Accept-Encoding;
		}
	}

	############# 自定义主机规则开始 ############

	if (req.url ~ "^http://") {
		set req.url = regsub(req.url, "http://[^/]*", "");
	}

	if (req.http.host ~ "^img.test.com")
	{
		# 删除COOKIE 提高命中
		# unset req.http.Cookie;

		set req.backend = img;
	}
	elseif (req.http.host ~ "^www.test.com")
	{
		set req.backend = app;
	}
	else
	{
		error 200 "Unknown virtual host";
	}

	# 扩展名为 php|cgi|asp|jsp|do|aspx 脚本的不缓存
	if (req.url ~ "\.(php|cgi|asp|jsp|do|aspx)($|\?)")
	{
		return (pass);
	}

	############# 自定义主机规则结束 ############

	# 不缓存GET或HEAD以外的请求
	if (req.request != "GET" && req.request != "HEAD") {
		return (pass);
	}

	# 不缓存验证信息和Cookie
	if (req.http.Authorization || req.http.Cookie) {
		return (pass);
	}

	# 所有缓存控制为 no-cache 的不缓存
	if (req.http.Cache-Control ~ "no-cache") {
		return (pass);
	}

	return (lookup);
}

sub vcl_hit
{
	if (req.request == "PURGE")
	{
		set obj.ttl = 0s;
		error 200 "Purged.";
	}

	return (deliver);
}

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

sub vcl_fetch
{
	# 设定默认缓存时长
	set beresp.ttl = 300s; #超时时长为300秒 

	# 定义缓存时长
	if (req.url ~ "\.(css|js|html|htm|xsl|xml)$") {
		set beresp.ttl = 300s; #超时时长为300秒 
	}

	# 图片/视频/音频/文档/压缩文件 缓存时常
	if (req.url ~ "\.(png|pdf|ppt|doc|docx|chm|rar|zip|bmp|jpeg|swf|ico|mp3|mp4|rmvb|ogg|mov|avi|wmv|swf|txt|png|gif|jpg)$") {
		set beresp.http.Pragma = "cache";
		set beresp.http.Cache-Control = "max-age=31536000, public";
		set beresp.ttl = 365d;
	}

	# 如果后端状态为 404 则缓存 600s
	if(beresp.status == 400 && beresp.status == 403 && beresp.status == 404) {
		set beresp.ttl = 600s;
	}

	# 如果后端服务器出现 500/501/502/503/504 错误时进入神圣模式 saintmode
	if (beresp.status == 500 || beresp.status == 501 || beresp.status == 502 || beresp.status == 503 || beresp.status == 504) {
		set beresp.saintmode = 20s;
		return (restart);
	}

	# grace时长,减少高并发下的穿透和争抢,设置缓存对象过期后还可以保留的时间
	set beresp.grace = 5m;

	return (deliver);
}

# 交付页面
sub vcl_deliver
{
	if (obj.hits > 0)
	{
		set resp.http.X-Cache = "HIT";
	}
	else
	{
		set resp.http.X-Cache = "MISS";
	}
	#去掉 varnish 中的一些头信息(如果你不想保留的话,建议保留 Age,方便查看)
	unset resp.http.X-Varnish;
	unset resp.http.Via;
	return (deliver);
}

# 自定义错误页面信息
sub vcl_error {
	set obj.http.Content-Type = "text/html; charset=utf-8";
	synthetic {"
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
	<head>
		<title>"} + obj.status + " " + obj.response + {"</title>
	</head>
	<body>
		<p style='font-family:Tahoma; font-size:14px;'>
		<b>Status</b>: "} + obj.status + {"<br>
		<b>Info</b>: "} + obj.response + {"<br>
		<b>XID</b>: "} + req.xid + {"<br></p>
	</body>
</html>
	"};
	return (deliver);
}

启动服务

Usage: /etc/init.d/varnish {start|stop|status|restart|condrestart|try-restart|reload|force-reload}

service varnish start

中文资料:

更多配置可参考http://my.oschina.net/jean/blog/189916

更多理论知识:http://my.oschina.net/jean/blog/189910

Varnish缓存策略及缓存时间计算方法说明:http://my.oschina.net/jean/blog/189908

Varnish3.0中文入门教程:http://anykoro.sinaapp.com/2012/01/31/varnish3-0中文入门教程

Varnish调优手记:http://my.oschina.net/u/572653/blog/178201

英文资料:

Varnish官方文档:

https://www.varnish-cache.org/docs/3.0/index.html

PHP的Varnish扩展,主要功能VarnishAdmin VarnishStat VarnishLog

http://www.php.net/manual/zh/book.varnish.php

用 Varnish 扩展 PHP 应用程序

http://www.ibm.com/developerworks/cn/opensource/os-php-varnish/

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!