解析Linux下Varnish缓存的配置优化


Posted in PHP onJune 20, 2013

Varnish是一款高性能的开源HTTP加速器,挪威最大的在线报纸 Verdens Gang 使用3台Varnish代替了原来的12台Squid,性能比以前更好。

但与老牌的squid相比,各有各的优劣势,网上大量的相对比较只是在其个人对自己熟悉的应用的最大使用上的发挥而已,可能squid到了有能力的人手上才足以发挥最强大的威力
Varnish采用了“Visual Page Cache”技术,在内存的利用上,Varnish比Squid具有优势,它避免了Squid频繁在内存、磁盘中交换文件,性能要比Squid高。

通过Varnish管理端口,可以使用正则表达式快速、批量地清除部分缓存,这一点是Squid不能具备的。
本人就varnish的一些见解与配置方法做简单的介绍与笔记

实验环境:Red Hat Enterprise Linux Server release 5.4 (Tikanga)
内核2.6.18-164.el5
yum install pcre-devel     ##预先安装一个软件包,不然会提示错误
tar zxvf varnish-2.1.3.tar.gz
cd varnish-2.1.3
./configure --prefix=/usr/local/varnish-2.1.3
make && make install
编辑配置文件,有模版,但太多注释,最好自己新建一个
vim /usr/local/varnish-2.1.3/etc/varnish/varnish.conf  
############下面附上配置文件的内容及注释#######################
#http请求处理过程
#1,receive请求入口状态,根据vcl判断pass还是lookup本地查询
#lookup,在hash表中查找数据,若找到则进入hit状态,否则进入fetch状态
#pass,选择后台,进入fetch状态
#fetch,对请求进行后端的获取,发送请求,获得数据,并进行本地存储
#deliver,将数据发送给客户端,进入done
#done,处理结束
##########配置后端服务器##############

backend linuxidc01 {
      .host = "192.168.1.142";
      .port = "7070";
      .probe = {
      .timeout = 5s;         
      .interval = 2s;          
      .window = 10;         
      .threshold = 8;     
      }
   }
backend linuxidc02 {
      .host = "192.168.1.141";
      .port = "7070";
      .probe = {
      .timeout = 5s;
      .interval = 2s;
      .window = 10;
      .threshold = 8;
      }
   }

##############配置后端服务器组,进行健康检测6秒,使用random方式设置权重########
#########另一种方式round-robin则默认轮询机制####################
director linuxidc15474 random
        { .retries = 6;
            { .backend = linuxidc02;
              .weight = 2;
             }
            { .backend = linuxidc01;
               .weight = 2;
            } 
        }

##########定义访问列表,允许下列地址清除varnish缓存#######################
acl local  {
         "localhost";
         "127.0.0.1";
          }

########从url判断针对哪类后面服务器及缓存配置############################
sub vcl_recv 
{
       if (req.http.host ~ "^linuxidc15474.vicp.net")  #匹配域名跳转后台服务器
            { set req.backend = linuxidc15474; }
         else { error 404 "Unknown HostName!"; }
        if (req.request == "PURGE")    #不允许非访问控制列表内的IP清除varnish缓存 
             { if (!client.ip ~ local)
                 {
                  error 405 "Not Allowed.";  
                  return (lookup);   
                 }
             }
        #清除url中有jpg等文件的cookie
        if (req.request == "GET" && req.url ~ "\.(jpg|png|gif|swf|jpeg|ico)$")
            {
              unset req.http.cookie;
             }   
        #判断req.http.X-Forwarded-For 如果前端有多重反向代理,这样可以获取客户端IP地址。
        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; }
##varnish实现图片的防盗链
#        if (req.http.referer ~ "http://.*) 
#          {
#             if ( !(req.http.referer ~ "http://.*vicp\.net" ||
#                   req.http.referer ~ "http://.*linuxidc15474\.net" ) )
#                 {
#                   set req.http.host = "linuxidc15474.vicp.net";
#                   set req.url = "/referer.jpg"; 
#                 }
#              return(lookup);
#          }
#         else {return(pass);}
       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请求的直接转发给后端服务器
        if (req.request != "GET" && req.request != "HEAD")
            { return (pass); }
        ##对GET请求,且url里以.php和.php?结尾的,直接转发给后端服务器
        if (req.request == "GET" && req.url ~ "\.(php)($|\?)")
            { return (pass); }
        ##对请求中有验证及cookie,直接转发给后端服务器
        if (req.http.Authorization || req.http.Cookie)
            { return (pass);}
         {
           ##除以上的访问请求,从缓存中查找
           return (lookup);
         }
       ##指定的font目录不进行缓存
       if (req.url ~ "^/fonts/")
           { return (pass); }
}
sub vcl_pipe 
            { return (pipe); }
##进入pass模式,请求被送往后端,后端返回数据给客户端,但不进入缓存处理 
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); 
      }
##在lookup后如果在cache中找到请求的缓存,一般以下面几个关键词结束
sub vcl_hit 
          { 
              if (!obj.cacheable) 
                { return (pass); } 
               return (deliver); 
          } 
##lookup后没有找到缓存时调用,以下面几个关键词结束,及调用fetch参数重新测试是否加入缓存
sub vcl_miss 
     { return (fetch); }
#让varnish服务器缓存的类型,从后端取得数据后调用
sub vcl_fetch 
  {    if (!beresp.cacheable) 
            { return (pass); } 
        if (beresp.http.Set-Cookie) 
           { return (pass); } 
       ##WEB服务器指明不缓存的内容,varnish服务器不缓存
       if (beresp.http.Pragma ~ "no-cache" || beresp.http.Cache-Control ~ "no-cache" || beresp.http.Cache-Control ~ "private") 
          { return (pass); }
       ##对访问中get有包含jpg,png等格式的文件进行缓存,缓存时间为7天,s为秒
      if (req.request == "GET" && req.url ~ "\.(js|css|mp3|jpg|png|gif|swf|jpeg|ico)$") 
         { set beresp.ttl = 7d; }
      ##对访问get中包含htm等静态页面,缓存300秒 
      if (req.request == "GET" && req.url ~ "\/[0-9]\.htm$") 
         { set beresp.ttl = 300s; }
           return (deliver); 
   }
####添加在页面head头信息中查看缓存命中情况########
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"; } 
  }

#########################以上为 varnish的配置文件##########################
创建用户:
groupadd www
useradd www -g www
创建 varnish_cache的缓存位置
mkdir /data/varnish_cache
启动varnish
ulimit -SHn 8192   ####设置文件描述符,因为我的机子性能并不好,可以按照自己的配置去设置
/usr/local/varnish-2.1.3/sbin/varnishd -u www -g www -f /usr/local/varnish-2.1.3/etc/varnish/varnish.conf -a 0.0.0.0:80 -s file,/data/varnish_cache/varnish_cache.data,100M -w 1024,8192,10 -t 3600 -T 127.0.0.1:3500
####-u 以什么用运行 -g 以什么组运行 -f varnish配置文件 -a 绑定IP和端口 -s varnish缓存文件位置与大小 -w 最小,最大线程和超时时间 -T varnish管理端口,主要用来清除缓存
#结束varnishd进程
pkill varnishd
启动varnishncsa用来将Varnish访问日志写入日志文件:
/usr/local/varnish-2.1.3/bin/varnishncsa -w /data/logs/varnish.log &
每天0点运行,按天切割Varnish日志,生成一个压缩文件,同时删除上个月旧日志的脚本(/var/logs/cutlog.sh):
vim /usr/local/varnish-2.1.3/etc/varnish/cut_varnish_log.sh
写入以下脚本:
#!/bin/sh
# This file run at 00:00
date=$(date -d "yesterday" +"%Y-%m-%d")
pkill -9 varnishncsa
mv /data/logs/varnish.log /data/logs/${date}.log
/usr/local/varnish-2.1.3/bin/varnishncsa  -w /data/logs/varnish.log &
mkdir -p /data/logs/varnish/
gzip -c /data/logs/${date}.log > /data/logs/varnish/${date}.log.gz
rm -f /data/logs/${date}.log
rm -f /data/logs/varnish/$(date -d "-1 month" +"%Y-%m*").log.gz
定时任务:
crontab -e
00 00 * * * /usr/local/varnish-2.1.3/etc/varnish/cut_varnish_log.sh

优化Linux内核参数
vi /etc/sysctl.conf
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.ip_local_port_range = 5000    65000
使配置生效
/sbin/sysctl -p

通过Varnish管理端口,使用正则表达式批量清除缓存
清除所有缓存
/usr/local/varnish-2.1.3/bin/varnishadm -T 127.0.0.1:3500 url.purge *$
清除image目录下所有缓存
/usr/local/varnish-2.1.3/bin/varnishadm -T 127.0.0.1:3500 url.purge /image/
127.0.0.1:3500 为被清除缓存服务器地址 www.linuxidc.com 为被清除的域名 /static/image/tt.jsp 为被清除的url地址列表
/usr/local/varnish-2.1.3/bin/varnishadm -T 127.0.0.1:3500 purge "req.http.host ~ www.linuxidc.com$ && req.url ~ /static/image/tt.jsp"
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
一个清除Squid缓存的PHP函数

<?php   
function purge($ip, $url)   
{   
    $errstr = '';   
    $errno = '';   
    $fp = fsockopen ($ip, 80, $errno, $errstr, 2);   
    if (!$fp)   
    {   
         return false;   
    }   
    else  
    {   
        $out = "PURGE $url HTTP/1.1\r\n";   
        $out .= "Host:blog.s135.com\r\n";   
        $out .= "Connection: close\r\n\r\n";   
        fputs ($fp, $out);   
        $out = fgets($fp , 4096);   
        fclose ($fp);   
        return true;   
    }   
}   purge("192.168.0.4", "/index.php");   
?>

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
配置开机自动启动Varnish
vim /etc/rc.d/rc.local
在末行写入以下内容:
ulimit -SHn 8192
/usr/local/varnish-2.1.3/sbin/varnishd -u www -g www -f /usr/local/varnish-2.1.3/etc/varnish/varnish.conf -a 0.0.0.0:80 -s file,/data/varnish_cache/varnish_cache.data,100M -w 1024,8192,10 -t 3600 -T 127.0.0.1:3500
/usr/local/varnish-2.1.3/bin/varnishncsa -w /data/logs/varnish.log &
查看Varnish服务器连接数与命中率:
/usr/local/varnish-2.1.3/bin/varnishstat
以上为varnish的状态,
1675         0.00         0.06 Client requests received   为服务端接收的客户端请求次数
179         0.00         0.01 Cache hits    为命中缓存,从缓存中取得数据返回给客户端的次数,即命中率
11         0.00         0.00 Cache misses  为跳过pass缓存,从后端服务应用中取得数据返回给用户的次数
用help看看可以使用哪些Varnish命令:
/usr/local/varnish-2.1.3/bin/varnishadm -T 127.0.0.1:3500 help
PHP 相关文章推荐
NOT NULL 和NULL
Jan 15 PHP
php循环输出数据库内容的代码
May 24 PHP
php 移除数组重复元素的一点说明
Nov 27 PHP
PHP中return 和 exit 、break和contiue 区别与用法
Apr 09 PHP
php从数组中随机抽取一些元素的代码
Nov 05 PHP
探讨捕获php错误信息方法的详解
Jun 09 PHP
PHP判断上传文件类型的解决办法
Oct 20 PHP
php实现处理输入转义字符的代码
Nov 08 PHP
PHP打印输出函数汇总
Aug 28 PHP
PHP微信企业号开发之回调模式开启与用法示例
Nov 25 PHP
php获取ajax的headers方法与内容实例
Dec 27 PHP
laravel实现上传图片,并且制作缩略图,按照日期存放的代码
Oct 16 PHP
解析PHP中常见的mongodb查询操作
Jun 20 #PHP
PHP 解决session死锁的方法
Jun 20 #PHP
解析PHP可变函数的经典用法
Jun 20 #PHP
使用PHP求两个文件的相对路径
Jun 20 #PHP
基于PHP服务端图片生成缩略图的方法详解
Jun 20 #PHP
解析thinkphp中的导入文件标签
Jun 20 #PHP
解析thinkphp import 文件内容变量失效的问题
Jun 20 #PHP
You might like
php 验证码制作(网树注释思想)
2009/07/20 PHP
解析PHP工厂模式的好处
2013/06/18 PHP
php输出1000以内质数(素数)示例
2014/02/16 PHP
php从字符串创建函数的方法
2015/03/16 PHP
Yii2.0框架实现带分页的多条件搜索功能示例
2019/02/20 PHP
laravel5.6 框架操作数据 Eloquent ORM用法示例
2020/01/26 PHP
sina的lightbox效果。
2007/01/09 Javascript
javasciprt下jquery函数$.post执行无响应的解决方法
2014/03/13 Javascript
NodeJS Express框架中处理404页面一个方式
2014/05/28 NodeJs
AngularJS动态绑定HTML的方法分析
2016/11/07 Javascript
js监听input输入框值的实时变化实例
2017/01/26 Javascript
Ajax和Comet技术总结
2017/02/19 Javascript
vue组件如何被其他项目引用
2017/04/13 Javascript
利用vue开发一个所谓的数独方法实例
2017/12/21 Javascript
JavaScript引用类型Function实例详解
2018/08/09 Javascript
细说webpack6 Babel的使用详解
2019/09/26 Javascript
JS面向对象编程实现的拖拽功能案例详解
2020/03/03 Javascript
Vue插槽_特殊特性slot,slot-scope与指令v-slot说明
2020/09/04 Javascript
Python实现字符串反转的常用方法分析【4种方法】
2017/09/30 Python
python遍历文件夹下所有excel文件
2018/01/03 Python
用Eclipse写python程序
2018/02/10 Python
Python实现的爬取网易动态评论操作示例
2018/06/06 Python
属性与 @property 方法让你的python更高效
2020/09/21 Python
美国眼镜在线零售商:Dualens
2019/12/07 全球购物
美国主要的特色咖啡和茶公司:Peet’s Coffee
2020/02/14 全球购物
杭州龙健科技笔试题.net部分笔试题
2016/01/24 面试题
办公室主任岗位职责
2013/11/08 职场文书
安全检查验收制度
2014/01/12 职场文书
买卖车协议书
2014/04/21 职场文书
大学生党员个人对照检查材料范文
2014/09/25 职场文书
2014年大学生工作总结
2014/11/20 职场文书
企业2014年度工作总结
2014/12/10 职场文书
感谢信怎么写
2015/01/21 职场文书
导游词之香港-太平山顶
2019/10/18 职场文书
Python 中的Sympy详细使用
2021/08/07 Python
nginx安装以及配置的详细过程记录
2021/09/15 Servers