解析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 相关文章推荐
ob_start(),ob_start('ob_gzhandler')使用
Dec 25 PHP
解决中英文字符串长度问题函数
Jan 16 PHP
PHP mb_convert_encoding 获取字符串编码类型实现代码
Apr 26 PHP
检查url链接是否已经有参数的php代码 添加 ? 或 &amp;
Feb 09 PHP
php代码中使用换行及(\n或\r\n和br)的应用
Feb 02 PHP
php 判断字符串中是否包含html标签
Feb 17 PHP
PHP生成迅雷、快车、旋风等软件的下载链接代码实例
May 12 PHP
php结合md5实现的加密解密方法
Jan 25 PHP
总结的一些PHP开发中的tips(必看篇)
Mar 24 PHP
php 调用百度sms来发送短信的实现示例
Nov 02 PHP
Laravel事件监听器用法实例分析
Mar 12 PHP
docker-compose部署php项目实例详解
Jul 30 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
PHP6 mysql连接方式说明
2009/02/09 PHP
查找mysql字段中固定字符串并替换的几个方法
2012/09/23 PHP
浅析Yii中使用RBAC的完全指南(用户角色权限控制)
2013/06/20 PHP
PHP 利用Mail_MimeDecode类提取邮件信息示例
2014/01/26 PHP
PHP常用算法和数据结构示例(必看篇)
2017/03/15 PHP
ie下动态加态js文件的方法
2011/09/13 Javascript
浏览器图片选择预览、旋转、批量上传的JS代码实现
2013/12/04 Javascript
DOM节点的替换或修改函数replaceChild()用法实例
2015/01/12 Javascript
Jquery使用小技巧汇总
2015/12/29 Javascript
第二次聊一聊JS require.js模块化工具的基础知识
2016/04/17 Javascript
Javascript基础知识盲点总结之函数
2016/05/15 Javascript
AngularJS入门教程之 XMLHttpRequest实例讲解
2016/07/27 Javascript
jQuery 获取页面li数组并删除不在数组中的key
2016/08/02 Javascript
用jmSlip编写移动端顶部日历选择控件
2016/10/24 Javascript
9个让JavaScript调试更简单的Console命令
2016/11/14 Javascript
详解vue-cli之webpack3构建全面提速优化
2017/12/25 Javascript
vue中element 上传功能的实现思路
2018/07/06 Javascript
nodejs实现范围请求的实现代码
2018/10/12 NodeJs
JavaScript实现表单注册、表单验证、运算符功能
2018/10/15 Javascript
Javascript迭代、递推、穷举、递归常用算法实例讲解
2019/02/01 Javascript
js利用递归与promise 按顺序请求数据的方法
2019/08/30 Javascript
JavaScript this关键字的深入详解
2021/01/14 Javascript
vue3.0中使用element的完整步骤
2021/03/04 Vue.js
python3生成随机数实例
2014/10/20 Python
python 字符串只保留汉字的方法
2018/11/16 Python
Python实现计算图像RGB均值方式
2020/06/04 Python
python软件测试Jmeter性能测试JDBC Request(结合数据库)的使用详解
2021/01/26 Python
HTML5视频播放插件 video.js介绍
2018/09/29 HTML / CSS
食品行业求职人的自我评价
2014/01/19 职场文书
党员四风问题对照检查材料
2014/09/27 职场文书
国庆节标语大全
2014/10/08 职场文书
幼儿园开学家长寄语(2015秋季)
2015/05/27 职场文书
2019年世界儿童日宣传标语
2019/11/22 职场文书
高端收音机+蓝牙音箱,JBL TUNER FM带收音蓝牙音箱评测
2021/04/24 无线电
SpringBoot集成Druid连接池连接MySQL8.0.11
2021/07/02 Java/Android
Java8 CompletableFuture 异步回调
2022/04/28 Java/Android