当前位置: 首页 > 工具软件 > varnish-agent > 使用案例 >

Varnish-2.1服务器安装配置文档

施阎宝
2023-12-01
 

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
export PKG_CONFIG_PATH=/usr/local/pcre-7.9/lib/pkgconfig
 
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) 例如:清除类似http://www.example.com/a/abc.html的URL地址:

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

(2) 例如:清除类似http://www.example.com/tech的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

 

 类似资料: