varnish反向代理缓存配置详解
http://www.varnish-cache.org
http://repo.varnish-cache.org/source/varnish-2.1.5.tar.gz
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=/soft/varnish
Varnish需要pcre支持,如果服务器没有安装pcre-devel会提示需要指定prce目录。
Centos服务器上使用yum install pcre-devel安装
安装:make install
/soft/varnish/etc/varnish/default.vcl
.host = "127.0.0.1";
.port = "80";
}
响应头信息
Server Apache/2.2.17 (Unix) PHP/5.3.3
Content-Type text/html;charset=ISO-8859-1
Content-Length 437
Date Mon, 28 Feb 2011 10:51:03 GMT
X-Varnish 1343878737 1343878732
Age 7
Via 1.1 varnish
Connection keep-alive
现在很多门户网站已经部署了varnish,并且反应都很好,甚至反应比squid还稳定,且效率更高,资源占用更少。相信在反向代理,web加速方面,varni
VCL内置的公用变量可以用在不同的VCL函数中,根据这些公用变量使用的不同阶段,下面依次介绍。
当请求到达后,可以使用的公用变量如表2所示:
表2
公用变量名称 含义
req.backend 指定对应的后端主机
server.ip 表示服务器端IP
client.ip 表示客户端IP
req.request 指定请求的类型,例如GET、HEAD、POST等
req.url 指定请求的地址
req.proto 表示客户端发起请求的HTTP协议版本
req.http.header 表示对应请求中的http头部信息
req. restarts 表示请求重启的次数,默认最大值为4
Varnish 在向后端主机请求时,可以使用的公用变量如表3所示:
表3
公用变量名称 含义
beresp.request 指定请求的类型,例如GET、HEAD等
beresp.url 指定请求的地址
beresp .proto 表示客户端发起请求的HTTP协议版本
beresp .http.header 表示对应请求中的http头部信息
beresp .ttl 表示缓存的生存周期,也就是cache保留多长时间,单位是秒
从cache或者后端主机获取内容后,可以使用的公用变量如表4所示:
表4
公用变量名称 含义
obj.status 表示返回内容的请求状态代码,例如200、302、504等
obj.cacheable 表示返回的内容是否可以缓存,也就是说,如果HTTP返回是200、203、300、301、302、404、410等,并且有非0的生存期,则可以缓存
obj.valid 表示是否是有效的HTTP应答
obj.response 表示返回内容的请求状态信息
obj.proto 表示返回内容的HTTP协议版本
obj.ttl 表示返回内容的生存周期,也就是缓存时间,单位是秒
obj.lastuse 表示返回上一次请求到现在的间隔时间,单位是秒
对客户端应答时,可以使用的公用变量如表5所示:
表5
公用变量名称 含义
resp.status 表示返回给客户端的HTTP状态代码
resp.proto 表示返回给客户端的HTTP协议版本
resp.http.header 表示返回给客户端的HTTP头部信息
resp.response 表示返回给客户端的HTTP状态信息
在上面的讲述中,我们只是介绍了常用的VCL内置公用变量,如果需要了解和使用更多的公用变量信息,请登录varnish官方网站查阅。
三 、配置一个简单的Varnish实例
由于版本的不同,Varnish配置文件的写法也存在一定差异,varnish2.x版本和1.x版本之间不但配置文件写法不同,而且新的版本功能也增加很多,并且去除了很多应用BUG,这里讲述的版本是varnish2.1.2,配置文件写法也以varnish2.x版本为基准。
Varnish安装完成后,默认的配置文件为/usr/local/varnish/etc/varnish/default.vcl,此文件内容默认全部被注释掉了,这里,我们以这个文件为模板,创建一个新的文件vcl.conf,并且放到/usr/local/varnish/etc目录下,配置完成的vcl.conf文件如下:
#通过backend定义了一个名称为webserver的后端主机,“.host”指定后端主机的IP地址或者域名,“.port”指定后端主机的服务端口。其中,“192.168.12.26”就是后端的一个web服务器。
.host = "192.168.12.26";
.port = "80";
}
sub vcl_recv {
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;
}
#如果请求的类型不是GET、HEAD、PUT、POST、TRACE、OPTIONS、DELETE时,进入pipe模式。注意这里是“&&”的关系。
if (req.request != "GET" &&
req.request != "HEAD" &&
req.request != "PUT" &&
req.request != "POST" &&
req.request != "TRACE" &&
req.request != "OPTIONS" &&
req.request != "DELETE") {
return (pipe);
}
#如果请求的类型不是GET与HEAD,则进入pass模式。
if (req.request != "GET" && req.request != "HEAD") {
return (pass);
}
if (req.http.host ~ "^(.*).ixdba.net" || req.http.host ~ "^(.*).ixdba.cn") {
set req.backend = webserver;
}
if (req.url ~ ".(jsp|do)($|?)") {
return (pass);
} else {
return (lookup);
}
}
sub vcl_pipe {
return (pipe);
}
sub vcl_pass {
return (pass);
}
sub vcl_hash {
set req.hash += req.url;
if (req.http.host) {
set req.hash += req.http.host;
} else {
set req.hash += server.ip;
}
return (hash);
}
sub vcl_hit {
if (!obj.cacheable) {
return (pass);
}
return (deliver);
}
sub vcl_miss {
return (fetch);
}
sub vcl_fetch {
if (!beresp.cacheable) {
return (pass);
}
if (beresp.http.Set-Cookie) {
return (pass);
}
if (req.url ~ "^/servlet/") {
return (pass);
}
if (req.url ~ "^/services/") {
return (pass);
}
if (req.request == "GET" && req.url ~ "^/upload(.*)$") {
set beresp.ttl = 300s;
}
#对于请求类型是GET,并且请求的URL以png、xsl、xml、gif、css、js等结尾时,则进行缓存,缓存时间为600秒。
if (req.request == "GET" && req.url ~ ".(png|xsl|xml|pdf|ppt|doc|docx|chm|rar|zip|bmp|jpeg|swf|ico|mp3|mp4|rmvb|ogg|mov|avi|wmv|swf|txt|png|gif|jpg|css|js|html|htm)$") {
set beresp.ttl = 600s;
}
return (deliver);
}
#下面是添加一个Header标识,以判断缓存是否命中。
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT from www.ixdba.net";
} else {
set resp.http.X-Cache = "MISS from www.ixdba.net";
}
return (deliver);
}
三、squid3.0安装及其配置
tar varnish-3.0.0.tar.gz
cd varnish-3.0.0
./configure --prefix=/usr/local/varnish3.0
make && make install
.host = "192.168.100.5";
.port = "80";
.connect_timeout = 1s;
.first_byte_timeout = 5s;
.between_bytes_timeout = 2s;
}
backend test2 {
.host = "192.168.100.6";
.port = "80";
.connect_timeout = 1s;
.first_byte_timeout = 5s;
.between_bytes_timeout = 2s;
}
#定义负载均衡
director lb_test random {
{
.backend = test1;
.weight = 5;
}
{
.backend = test2;
.weight = 5;
}
#定义访问控制列表
acl purge {
"localhost";
"127.0.0.1";
"192.168.100.0"/24;
"192.168.0.0"/24;
}
#开启压缩模式,图片格式取消压缩
if (req.http.Accept-Encoding) {
if (req.url ~ ".(jpg|png|gif|jpeg|flv)" ) {
remove req.http.Accept-Encoding;
remove req.http.Cookie;
} else if (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} else if (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else {
remove req.http.Accept-Encoding;
}
}
#根据host设置后端服务器
if (req.http.Host ~ "(?i)(www.test1.com|www.test2.com)") {
set req.backend = lb_test;
}else
if (req.http.Host ~ "(?i)image.wdj.com"){
set req.backend = test1;
}else
{
error 408 "Hostname not found";
}
#如果为purge请求,客户端ip不在访问列表中,返回405拒绝
if (req.request == "PURGE") {
if (!client.ip ~purge) {
error 405 "Not Allowed";
}
#本地缓存查找
return(lookup);
}
#如果为GET请求,url后缀为jpg,png,gif等 取出cookie
if (req.request == "GET"&&req.url ~ "(?i).(jpg|png|gif|swf|jpeg|ico)$") {
unset req.http.cookie;
}
#如果GET请求,url为php,则穿过cache,不缓存
if (req.request =="GET"&&req.url ~ "(?i).php($|?)"){
return (pass);
}
#简单防盗链
if (req.http.referer ~ "http://.*") {
if ( !(req.http.referer ~ "http://.*test1.com"
|| req.http.referer ~ "http://.*test2.com"
|| req.http.referer ~ "http://.*wdj.com"
|| req.http.referer ~ "http://.*google.com"
|| req.http.referer ~ "http://.*baidu.com"
|| req.http.referer ~ "http://.*yahoo.cn"
)) {
error 404 "Not Found!";
}
}
#获取客户端ip
# 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;
}
# }
#不是以下请求进入pipe模块
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);
}
#不是GET 和HEAD请求不缓存
if (req.request != "GET" && req.request != "HEAD") {
/* We only deal with GET and HEAD by default */
return (pass);
}
if (req.http.Authorization) {
/* Not cacheable by default */
return (pass);
}
return (lookup);
}
#
sub vcl_pipe {
return (pipe);
}
#
sub vcl_pass {
return (pass);
}
#使用url+host hash算法查找数据
sub vcl_hash {
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
return (hash);
}
# 如果请求为purge 将清除缓存
sub vcl_hit {
if (req.request == "PURGE") {
set obj.ttl = 0s;
error 200 "Purged";
}
return (deliver);
}
return (fetch);
}
sub vcl_fetch {
if (beresp.ttl <= 0s ||
beresp.http.Set-Cookie ||
beresp.http.Vary == "*") {
/*
* Mark as "Hit-For-Pass" for the next 2 minutes
*/
set beresp.ttl = 0 s;
return (hit_for_pass);
}
if (beresp.http.Pragma ~"no-cache" ||
beresp.http.Cache-Control ~"no-cache" ||
beresp.http.Cache-Control ~"private") {
return (deliver);
}
if (req.request == "GET"&&req.url ~ "(?i).(js|css|mp3|jpg|png|gif|swf|jpeg|ico)$") {
set beresp.ttl = 30d;
}
if (req.request == "GET"&&req.url ~ "(?i).(html|htm)$") {
set beresp.ttl = 1d;
}
return (deliver);
}
sub vcl_deliver {
set resp.http.x-hits = obj.hits;
if (obj.hits > 0) {
set resp.http.X-Cache = "Hit test.com";
}else {
set resp.http.X-Cache = "Miss test.com";
}
set resp.http.Server = "BWM";
return (deliver);
}
sub vcl_error {
set obj.http.Content-Type = "text/html; charset=utf-8";
set obj.http.Retry-After = "5";
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>
<h1>Error "} + obj.status + " " + obj.response + {"</h1>"} + obj.response + {"<h3>Guru Meditation:</h3>XID: "} + req.xid + {"<hr>Varnish cache server
</body>
</html>
"};
return (deliver);
}
return (ok);
}
return (ok);
}
四、启动
启动命令
/usr/local/varnish3.0/sbin/varnishd -f /usr/local/varnish3.0/etc/varnish/default.vcl -s malloc,2G -a 0.0.0.0:80 -w 1024,51200,10 -t
3600 -T 192.168.100.2:3500
检测配置文件是否存在错误
/usr/local/varnish3.0/sbin/varnishd -C -f /usr/local/varnish3.0/etc/varnish/default.vcl
参数
-a address:port 监听端口
-f 指定配置文件
-s 指定缓存类型 malloc为内存, file 文件缓存
-t 默认TTL
-T address:port 管理端口
-w 最小线程,最大线程,超时时间
/usr/local/varnish3.0/bin/varnishncsa -w /var/logs/varnish.log &
五、缓存刷新
function purge($ip, $url)
{
$errstr = '';
$errno = '';
$fp = fsockopen ($ip, 80, $errno, $errstr, 2);
if (!$fp)
{
return false;
}
else
{
$out = "PURGE $url HTTP/1.1rn";
$out .= "Host:image.wdj.comrn";
$out .= "Connection: closernrn";
fputs ($fp, $out);
$out = fgets($fp , 4096);
fclose ($fp);
return true;
}
}
if(isset($_POST['content'])) {
//$str=str_replace("r","
",$_POST[content]);
$arr=(explode("n",$_POST['content']));
$Server="192.168.100.2";
foreach ($arr as $value)
{
echo $value;
purge($Server, $value);
echo "刷新成功"."<br />";
}
//purge($Server, "$_POST[content]");
//echo "刷新成功";
}
?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>varnish缓存刷新</title>
</head>
<body>
<form action="?" method="post">
填写需要刷新url<br />
<textarea name="content" cols="40" rows="10"></textarea>
<input type="submit" value="submit" />
</form>
</body>
</html>
通过管理端口清除缓存
telnet 192.168.100.2 3500
3.0版本 为ban.url aaaa.html
2.版本为purge.url aaaa.html
vcl.load 配置文件名 文件路径
例如vcl.load 123 /usr/local/varnish3.0/etc/varnish/default.vcl。
您可能感兴趣的文章:
Varnish2.1.4配置缓存服务器
varnish反向代理缓存配置详解
Drupal7配合Varnish使用及整合drupal模块的详细教程
varnish缓存策略及缓存时间计算方法
varnish 503和varnish 400错误的解决方法
varnish的VCL的配置详解
Ubuntu下varnish的安装配置文档
使用Xcache加速你的PHP网站
php怎么处理高并发问题?
mysql加速查询速度利器之查询缓存