解析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 相关文章推荐
用PHP的ob_start();控制您的浏览器cache!
Nov 25 PHP
php 获取完整url地址
Dec 20 PHP
php array的学习笔记
May 10 PHP
PHP读取PDF内容配合Xpdf的使用
Nov 24 PHP
php源代码安装常见错误与解决办法分享
May 28 PHP
php数组去重实例及分析
Nov 26 PHP
PHP中绘制图像的一些函数总结
Nov 19 PHP
php控制文件下载速度的方法
Mar 24 PHP
Yii针对添加行的增删改查操作示例
Oct 18 PHP
PHP PDOStatement::debugDumpParams讲解
Jan 30 PHP
PHP PDOStatement::rowCount讲解
Feb 01 PHP
Laravel 5.5 异常处理 &amp; 错误日志的解决
Oct 17 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删除文件夹的三种方法
2013/06/09 PHP
ASP.NET jQuery 实例1(在TextBox里面创建一个默认提示)
2012/01/13 Javascript
禁止页面刷新让F5快捷键及右键都无效
2014/01/22 Javascript
js和css写一个可以自动隐藏的悬浮框
2014/03/05 Javascript
javascript 控制input只允许输入的各种指定内容
2014/06/19 Javascript
基于javascript实现图片懒加载
2016/01/05 Javascript
JavaScript实现广告弹窗效果
2016/08/09 Javascript
javascript兼容性(实例讲解)
2017/08/15 Javascript
JSON创建键值对(key是中文或者数字)方式详解
2017/08/24 Javascript
js中实例与对象的区别讲解
2019/01/21 Javascript
浅谈Webpack多页应用HMR卡住问题
2019/04/24 Javascript
vue实现pdf文档在线预览功能
2019/11/26 Javascript
[03:55]2016国际邀请赛中国区预选赛首日TOP10精彩集锦
2016/06/27 DOTA
Python的SQLalchemy模块连接与操作MySQL的基础示例
2016/07/11 Python
Python在线运行代码助手
2016/07/15 Python
基于python爬虫数据处理(详解)
2017/06/10 Python
Django中ORM表的创建和增删改查方法示例
2017/11/15 Python
教你使用python实现微信每天给女朋友说晚安
2018/03/23 Python
利用scrapy将爬到的数据保存到mysql(防止重复)
2018/03/31 Python
Python中numpy模块常见用法demo实例小结
2019/03/16 Python
Python.append()与Python.expand()用法详解
2019/12/18 Python
Python图像处理库PIL的ImageFilter模块使用介绍
2020/02/26 Python
python如何求100以内的素数
2020/05/27 Python
印尼太阳百货公司网站:Matahari
2018/02/04 全球购物
商得四方公司面试题(gid+)
2014/04/30 面试题
五一家具促销方案
2014/01/10 职场文书
公司运动会策划方案
2014/05/25 职场文书
公证委托书格式
2014/09/13 职场文书
国防教育标语
2014/10/08 职场文书
2014年单位工作总结范文
2014/11/27 职场文书
护士求职自荐信范文
2015/03/04 职场文书
2016年领导干部正风肃纪心得体会
2015/10/09 职场文书
Go遍历struct,map,slice的实现
2021/06/13 Golang
Django Paginator分页器的使用示例
2021/06/23 Python
零基础学java之循环语句的使用
2022/04/10 Java/Android
SQL Server携程核心系统无感迁移到MySQL实战
2022/06/01 SQL Server