Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2233287
  • 博文数量: 533
  • 博客积分: 8689
  • 博客等级: 中将
  • 技术积分: 7046
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-26 10:00
文章分类

全部博文(533)

文章存档

2024年(2)

2023年(4)

2022年(16)

2014年(90)

2013年(76)

2012年(125)

2011年(184)

2010年(37)

分类: LINUX

2011-04-26 16:29:10

Varnish权威指南(中文)

http://linuxguest.blog.51cto.com/195664/354889





以下是我的配置文档

vi default.vcl

 

backend bbs {

   .host = "192.168.0.144";

   .port = "80";

}

backend bbs1 {

   .host = "192.168.0.155";

   .port = "80";

}

 

acl local {

        "localhost";

        "127.0.0.1";

}

 

 

sub vcl_recv {

      if (req.http.host ~ "^(www.)?bbs.com$") {

         set req.backend = bbs;

      }

      elsif (req.http.host ~ "^(www.)?bbs1.com$") {

         set req.backend = bbs1;

      }     

       else {

           error 404 "Unknown HostName!";

      }

      if (req.request == "PURGE") {

         if (!client.ip ~ local) {

             error 405 "Not Allowed.";

             return (lookup);

             }

      }

      if (req.request == "GET" && req.url ~ "\.(jpg|png|gif|swf|jpeg|ico)$") {

         unset req.http.cookie;

      }

      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") {

         return (pipe);

      }

      if (req.request != "GET" && req.request != "HEAD") {

         return (pass);

      }

      if (req.http.Authorization || req.http.Cookie) {

         return (pass);

      }

 

   if (req.request == "GET" && req.url ~ "\.(php)($|\?)") {

  return (pass);

    }

   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 (beresp.http.Pragma ~ "no-cache" ||

    beresp.http.Cache-Control ~ "no-cache" ||

    beresp.http.Cache-Control ~ "private") {

    return (pass);

}

 

 

     if (req.request == "GET" && req.url ~ "\.(js|css|mp3|jpg|png|gif|swf|jpeg|ico)$")

{

         set beresp.ttl = 7d;

     }

 

     return (deliver);

}

 

sub vcl_deliver {

             set resp.http.x-hits = obj.hits ;

             if (obj.hits > 0) {

                         set resp.http.X-Cache = "HIT cqtel-bbs";

             } else {

                    set resp.http.X-Cache = "MISS cqtel-bbs";

             }

}

 

 

 

sub vcl_error {

     set obj.http.Content-Type = "text/html; charset=utf-8";

     synthetic {"

  "">

  

     "} obj.status " " obj.response {"

  

  

    

Error "} obj.status " " obj.response {"

    

"} obj.response {"

    

Guru Meditation:

    

XID: "} req.xid {"

    


    

        bbs cache server

    

  

"};

     return (deliver);

}




启动参数:



/usr/local/varnish/sbin/varnishd -f /usr/local/varnish/etc/varnish/default.vcl -a 192.168.100.182:80 -u www -g www -p thread_pool_max=51200 -p thread_pools=8 -h classic,500009 -p lru_interval=20 -s file,/data/varnish/varnish_cache.data,51200M -w 1000,51200,10 -T 192.168.100.182:3500

 




















































1、Varnish简介
Varnish 是一款高性能且开源的反向代理服务器(Reverse Proxy Server),挪威最大的线上报纸 Verdens Gang 使用3台Varnish代替了原本的12台Squid, 性能比以前更好。Varnish 的作者 Poul-Henning Kamp 是 FreeBSD 核心的开发人员之一,他认为现在的电脑比起1975年已经复杂许多。在那个时代,存储媒介只有两种:记忆体与硬盘。但现在电脑系统的记忆体除了主记忆体 外,还包括了CPU内的L1、L2,甚至有L3快取。硬盘上也有自己的快取装置,因此squid cache自行处理物件替换的架构不可能得知这些情況而做到最佳化,但作业系统可以得知这些情況,所以这部份的工作有关交给作业系统处理,这就是 Varnish Cache 的设计架构。
一般來说,使用Varnish代替Squid的理由有三点:

1.1 Varnish采用了“Visual Page Cache”技术,在记忆体的利用上,Varnish 比 Squid 更具有优势,它避免了Squid频繁在记忆体、硬盘中交换文件,性能比 Squid 还高。
1.2 Varnish的稳定性高,进行相同工作的Squid服务器发生故障的几率似乎比Varnish高。
1.3 通过Varnish管理端口,可以使用正则表达式、批量地清除部分缓存,这一点是Squid不能具备的。

2、Linux 系统安裝 Varnish 的过程:
2.1 首先建立www用戶和组,以及Varnish缓存存放目录:

sudo /usr/sbin/groupadd www -g 48
sudo /usr/sbin/useradd -u 48 -g www www
sudo mkdir -m 755 /data/varnish/vcache
sudo chown -R www:www /data/varnish/vcache

2.2 建立 Varnish 日志目录:

sudo mkdir -m 755 /data/varnish/logs/
sudo chown -R www:www /data/varnish/logs/

2.3 代码快速获取地址:

wget http://down.hiphp.com/ports/nginx/pcre-7.9.tar.gz
wget http://down.hiphp.com/ports/varnish/varnish-2.1.tar.gz


2.4 源代码安装Varnish

tar zxvf pcre-7.9.tar.gz
cd pcre-7.9/
./configure --prefix=/usr/local/webserver/pcre-7.9/
make && make install
cd ../
 
设置 PKG_CONFIG_PATH
 
tar -zxvf varnish-2.1.tar.gz
cd varnish-2.1
./configure --prefix=/usr/local/varnish-2.1/ --enable-dependency-tracking --enable-debugging-symbols --enable-developer-warnings
make
make install

注:如果你的gcc版本是4.2.0或更高的版本,可以加上–enable-extra-warnings编译参数,在出错时,得到附加的警告信息。
我这里是用源码包安装的,如果你是redhat或centos可以用rpm包来安装

3、编辑配置文件 /usr/local/varnish-2.1/etc/varnish/default.vcl:
这里我对这段配置文件说明一下:
(1) Varnish通过反向代理访问192.168.1.104和192.168.1.105,端口为80的Web服务器;
(2) Varnish对hiphp.com或者hiphpimg.com域名进行缓存;
(3) Varnish对以.asp和.cgi已经带有?的URL直接从源服务器取;
(4) Varnish对fetch里边符合正则表达式的连接进行指定时间的缓存。

下面是我的范例配置文件:

backend web4 {
.host = "192.168.1.104";
.port = "80";
.probe = {
.timeout = 50 ms;
.interval = 5s;
.window = 10;
.threshold = 8;
.request =
"GET /index.php HTTP/1.1"
"Host: 192.168.1.104"
"Connection: close"
"Accept-Encoding: foo/bar" ;
}
}
backend web5 {
.host = "192.168.1.105";
.port = "80";
.probe = {
.timeout = 50 ms;
.interval = 5s;
.window = 10;
.threshold = 8;
.request =
"GET /index.php HTTP/1.1"
"Host: 192.168.1.105"
"Connection: close"
"Accept-Encoding: foo/bar" ;
}
}
director web random {
{ .backend = web4; .weight = 1; }
{ .backend = web5; .weight = 1; }
}
 
sub vcl_recv {
set req.grace = 30s;
 
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);
}
if (req.request != "GET" && req.request != "HEAD") {
/* We only deal with GET and HEAD by default */
return (pass);
}
# if (req.http.Authorization || req.http.Cookie) {
# /* Not cacheable by default */
# return (pass);
# }
# if (req.http.user-agent ~ "(.*)(Nokia|Sony|Ericsson|Motorola|Samsung|Lg|Sie-|Philips|Panasonic|Alcatel|Lenovo|Cldc|Midp|Wap|Mobile)(.*)")
# {
# error 750 "ganji.cn";
# }
if (req.http.host ~ "^(.*).hiphp.com" || req.http.host ~ "^(.*).hiphpimg.com") {
set req.backend = web;
}
if (req.url ~ "\.(asp|cgi)($|\?)") {
return (pass);
} else {
return (lookup);
}
}
 
#sub vcl_error {
# if (obj.status == 750)
# {
# if (req.http.host ~ "^(.*).ganji.com")
# {
# set obj.http.Location = "http://"regsub(req.http.host,"com","cn");
# }
# }
# set obj.status = 302;
# return (deliver);
#}
sub vcl_pipe {
# Note that only the first request to the backend will have
# X-Forwarded-For set. If you use X-Forwarded-For and want to
# have it set for all requests, make sure to have:
# set req.http.connection = "close";
# here. It is not set by default as it might break some broken web
# applications, like IIS with NTLM authentication.
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 {
set req.grace = 30s;
if (!beresp.cacheable) {
return (pass);
}
if (beresp.http.Set-Cookie) {
return (pass);
}
#Not to cache
if (req.url ~ "^/vip/") {
return (pass);
}
#To cache
if (req.request == "GET" && req.url ~ "\/[0-9]{4}\.htm$") {
set beresp.ttl = 300s;
}
if (req.request == "GET" && req.url ~ "^/[a-z]+\d?/$") {
set beresp.ttl = 300s;
}
if (req.request == "GET" && req.url ~ "^/fang(.*)$") {
set beresp.ttl = 300s;
}
if (req.request == "GET" && req.url ~ "^/piao(.*)$") {
set beresp.ttl = 20s;
}
if (req.request == "GET" && req.url ~ "\.(png|swf|txt|png|gif|jpg|css|js|htm)$") {
set beresp.ttl = 3600s;
}
if (req.request == "GET" && req.url ~ "\/([0-9]+)_([0-9]*)\.htm$") {
set beresp.ttl = 3104000s;
}
return (deliver);
}
 
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT from bj-185.cache.ganji.com";
} else {
set resp.http.X-Cache = "MISS from bj-185.cache.ganji.com";
}
return (deliver);
}

4、用适当权限启动 Varnish

ulimit -SHn 51200 
/usr/local/varnish-2.1/sbin/varnishd -f /usr/local/varnish-2.1/etc/varnish/default.vcl -a 192.168.1.185:80 -u www -g www -p thread_pool_max=51200 -p thread_pools=8 -h classic,500009 -p lru_interval=20 -s file,/data/varnish/varnish_cache.data,51200M -w 1000,51200,10 -T 192.168.1.185:3500

5、配置开机自动启动 Varnish
编辑启动执行脚本/etc/rc.local並将上面內容贴到最下方,也可以写成一个启动脚本varnish.sh

6、启动 varnishncsa,用来将Varnish访问日志写入日志文件:

/usr/local/varnish-2.1/bin/varnishncsa -a -w /data/varnish/logs/varnish.log &

7、Varnish 优化
7.1 优化Linux核心参数

编辑/etc/sysctl.conf 在底部增加以下内容:
net.ipv4.tcp_keepalive_time = 300
#表示当Keepalive起用的时候,TCP发送keepalive消息的频繁度。预设值是2小时,这里我改为5分钟。
net.ipv4.tcp_tw_reuse = 1
#表示开启重用。允許將TIME-WAIT sockets重新用於新的TCP連接,預設为0,表示开关,我將它开啟。
net.ipv4.tcp_tw_recycle = 1
#表示开启TCP連接中TIME-WAIT sockets的快速回收,预设为0,表示开关,我将它开启。
net.ipv4.tcp_max_tw_buckets = 5000
#表示系統同时保持TIME_WAIT套接字的最大属性,如果超过这个数字,TIME_WAIT套接字將立刻被清除並印出警告訊息。预设是180000,改为5000

之后记得执行 /sbin/sysctl -p 使配置生效。

以下配置是官网上提供:(官网上说,这个配置可以支持4000-8000 req/s的压力.)

net.ipv4.ip_local_port_range = 1024 65536
#表示用來向外连接的端口范围。预设情况下很小:3276861000,我将它改为102465536
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_wmem=4096 65536 16777216
net.ipv4.tcp_fin_timeout = 3
#表示如果套接字由本端要求开放,这个参数决定了它保持在FIN-WAIT-2状态的时间。
net.core.netdev_max_backlog = 30000
net.ipv4.tcp_no_metrics_save=1
net.core.somaxconn = 262144
net.ipv4.tcp_syncookies = 0
#表示开启SYN Cookies。当出现SYN等待对列溢出时,启用cookies來处理,可防范少量SYN攻击,预设为0
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_syn_backlog = 262144
#表示SYN队列的长度,预设为1024,加大队列长度为262144,可容纳更多等待连接的网路连接数。
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2

7.2 系统环境优化

    ulimit -HSn 131072
ulimit -HSc unlimited

7.3 VCL优化

    vcl_recv:      set req.grace = 30s;
vcl_fetch: set obj.grace = 30s;

7.4 参数优化.(“telnet localhost 5000″后,输入”param.show”可以看到所有系统运行中的参数.输入”param.set thread_pools 8″可以调整参数.)

    thread_pools                  8 [pools]
thread_pool_max 2000 [threads]
thread_pool_min 100 [threads]
thread_pool_timeout 10 [seconds]
#这四个参数要一起看.
#thread_pools是系统sess进入处理的pools.理想的情况下是一个cpu一个pool,如果pools过多会消耗cpu时间和mem.但是,pools多一点,处理并发的能力会更强.
#thread_pool_min是每个pools的最小threads数.当pools侦测到可处理sess后,就分配给所属的空余threads处理.
#thread_pool_max是所有pools所属的threads总和数的上限值.这个值不要设置的太高,一般是系统期望峰值的90%.太高了会发生"pile-ups",不知道怎么翻译,是不是"拥挤"?
#thread_pool_timeout是thread的过期时间.当threads数大于thread_pool_min的时候,thread的空闲超过thread_pool_timeout时间,thread就被释放.
 
listen_depth 1024 [connections] #tcp链接队列size.默认是512,适当调大一点,处理并发能力增强.
lru_interval 20 [seconds]
#优雅时间参数(不知道是不是应该这么翻译),意思就是,如果一个object,在内存中超过了这个时间还没有被重用,则把这个对象移动到 LRU(Least Recently Used)队列中.一种普遍的cache算法.个人理解,提高这个时间,会减少object在内存中的copy,以提高运行效率.

8、接下來看看如何管理Varnish:
8.1 查看 Varnish 服务器连接数与命中率:

/usr/local/varnish-2.1/bin/varnishstat

8.2 通过 Varnish 管理端口進行管理(用 –help查看可用的指令)

/usr/local/varnish-2.1/varnishadm -T 127.0.0.1:3500 help

8.3 通过Varnish管理端口,使用正则表达式批量清除缓存:
(1) 例如:清除类似的URL地址:

/usr/local/varnish-2.1/bin/varnishadm -T 127.0.0.1:3500 url.purge /a/

(2) 例如:清除类似的URL地址:

/usr/local/varnish-2.1/bin/varnishadm -T 127.0.0.1:3500 url.purge w*$

(3) 例如:清除所有缓存:

/usr/local/varnish-2.1/bin/varnishadm -T 127.0.0.1:3500 url.purge *$

8.4 下面是一个每天0点执行,按天切割Varnish日志,生成一个压缩文档,同时删除上个月旧日志的腳本(/usr/local/shell/cutlog.sh):

#!/bin/sh
# This file run at 00:00
date=$(date -d "yesterday" +"%Y-%m-%d")
pkill -9 varnishncsa
mv /data/varnish/logs/varnish.log /data/varnish/logs/${date}.log
/usr/local/varnish-2.1/bin/varnishncsa -a -w /data/varnish/logs/varnish.log &
gzip -c /data/varnish/logs/${date}.log > /data/varnish/logs/${date}.log.gz
rm -f /data/varnish/logs/${date}.log
rm -f /data/varnish/logs/$(date -d "-1 month" +"%Y-%m*").log.gz

设定在每天早上00:00定时执行:

sudo /usr/bin/crontab -e

添加以下內容

0 0 * * * /usr/local/shell/cutlog.sh

8.5 如果你要确定varnish是否有正确执行,你可以用netstat -atp看有沒有一个正在监听的3500端口,或者用pa aux | grep varnishd看这个程序是否有在运行。
8.6 Varnish监控程序使用

/usr/local/varnish-2.1/bin/varnishtop  -i rxheader -I Referer
/usr/local/varnish-2.1/bin/varnishtop -i rxurl
/usr/local/varnish-2.1/bin/varnishlog -o -c ReqStart 192.168.113.171

阅读(1310) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~