设为首页 收藏本站
查看: 577|回复: 0

[经验分享] varnish详解

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2016-11-11 09:46:37 | 显示全部楼层 |阅读模式
简介:
    varnish是一个web应用加速器也称为cache型的http反向代理,与传统的 squid 相比,varnish 具有性能更高、速度更快、管理更加方便等诸多优点,除了它的性能,配置语言VCL使得它可以非常灵活,VCL可以让我们编写请求和响应的处理策略,策略可以决定提供什么服务、从哪获取内容以及请求和响应报头怎样修改。


特点:


    • 重启后缓存数据失效;
    • 利用虚拟内存方式,I/O 性能好;
    • VCL 配置管理比较灵活;
    • 具有强大的管理功能,top、stat、admin、list 等;
    • 状态机设计巧妙,结构清晰;
    • 利用二叉堆管理缓存文件,达到积极删除目的。


下载安装:    CentOS6.8    varnish-4.0.3-1.el6.x86_64

     CentOS上配置好epel源可直接yum安装:

]# yum isntall varnish
    若想下载较新版本可从官方网站找到yum源:
    http://varnish-cache.org/release ... html#install-redhat

      安装后主要文件及命令:

        主配置文件:
            /etc/sysconfig/varnish  配置varnish工作特性,监听的地址和端口,缓存机制等;
            /etc/varnish/default.vcl 各Child/Cache线程的工作属性,缓存策略配置
        主程序:
            /usr/sbin/varnishd
        CLI命令行接口:
            /usr/bin/varnishadm
        Shared Memory Log交互工具:
            /usr/bin/varnishhist
            /usr/bin/varnishlog
            /usr/bin/varnishncsa
            /usr/bin/varnishstat
            /usr/bin/varnishtop
        测试工具程序:
            /usr/bin/varnishtest
        VCL配置文件重载程序:
            /usr/sbin/varnish_reload_vcl
        服务启动脚本:

            /etc/rc.d/init.d/varnish
    启动varnish:
        ]# varnishd -f /etc/varnishd/default.vcl -s file,/var/varnish_cache,1G\

            -T 127.0.0.0:6081 -a 0.0.0.0:80

        各选项解释:
        -f 指定 varnish 的配置文件位置

        -s 指定 varnish 缓存存储机制,下面有解释
        -T address:port 设定 varnish 的管理地址及其端口,用于 varnishadm 管理
        -a address:port 接收请求的地址及端口,缓存的后方应用为 http 则可将端口设为 80

     注: 一般 varnish 的启动选项定义在 /etc/sysconfig/varnish 文件中,以各变量的值作为运行参数,当使用 service varnish start 方式启动服务时会自动加载该文件,文件内容较为容易理解,需注意最后的 # DAEMON_OPTS="" 该变量可添加启动时的额外选项,如:
DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300"
以指定最大空闲线程数、最大线程数、线程超时时长等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
...

# # DAEMON_OPTS is used by the init script.  If you add or remove options, make
# # sure you update this section, too.
DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \
             -f ${VARNISH_VCL_CONF} \
             -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \
             -t ${VARNISH_TTL} \
             -p thread_pool_min=${VARNISH_MIN_THREADS} \
             -p thread_pool_max=${VARNISH_MAX_THREADS} \
             -p thread_pool_timeout=${VARNISH_THREAD_TIMEOUT} \
             -u varnish -g varnish \
             -S ${VARNISH_SECRET_FILE} \
             -s ${VARNISH_STORAGE}"
#
## Alternative 4, Do It Yourself. See varnishd(1) for more information.
#
# DAEMON_OPTS=""




varnish的缓存存储机制( Storage Types):


    • malloc[,size]

         内存存储,使用malloc()库调用在varnish启动时向操作系统申请指定大小的内存空间以存储缓存对象;可能会产生内存碎片,影响性能


    • file[,path[,size[,granularity]]]

         文件存储,黑盒,使用特定单个文件存储全部的缓存数据,并通过操作系统的mmap()系统调用将整个缓存文件映射至内存区域,重启后所有缓存项失效;


    • persistent,path,size

     与file功能相同,黑盒,但可以持久存储数据;目前测试阶段;

可在/etc/sysconfig/varnish文件中定义VARNISH_STORAGE=;或varnishd -s TYPE

Varnish无法追踪某缓存对象是否存入了缓存文件,从而也就无从得知磁盘上的缓存文件是否可用,因此,file存储方法在varnish停止或重启时会清除数据。


设计结构:

QQ截图20161111093941.png


工作流程:

     Varnish 与一般服务器软件类似,分为 master 进程和 child 进程。Master 进程读入存储配置文件,调用合适的存储类型,然后创建 / 读入相应大小的缓存文件,接着 master 初始化管理该存储空间的结构体,然后 fork 并监控 child 进程。Child 进程分配若干线程进行工作,主要包括一些管理线程和很多 worker 线程。

      Varnish 的某个负责接收新 HTTP 连接线程开始等待用户,如果有新的 HTTP 连接过来,它总负责接收,然后唤醒某个等待中的线程,并把具体的处理过程交给它。Worker 线程读入 HTTP 请求的 URI,查找已有的 object,如果命中则直接返回并回复用户。如果没有命中,则需要将所请求的内容,从后端服务器中取过来,存到缓存中,然后再回复。具体决策操作流程由vcl各状态引擎实现

QQ截图20161111094005.png

配置Varnish
VCL简介:    VCL(varnish configuration language)是 varnish 域专用的配置语言,用来描述请求处理过程、定义数据的存储策略。VCL 语法比较简单,和 C 和 Perl 比较相似。当新的配置被加载时,主控进程会启用vcc将配置文件编译成二进制程序(所以依赖到 gcc 环境),并组织成共享对象(Shared Object)交由Child进程加载使用,若编译失败会返回相应错误,varnish运行时可随时加载配置文件。

想要配置varnish正常工作。需先了解varnish 的配置语言VCL,“域专用”指的是有些数据仅出现于特定的状态中。

    • VCL文件以 vcl 4.0 为起始;    /etc/varnish/default.vcl
    • //,#,/*..*/ 为注释
    • sub定义一个subroutings
    • 没有循环,有限状态
    • 以一个关键词作为返回状态参数以表示下一步动作,即:return(action)
    • 域专用的配置语言
    • 操作符:=、==、~、!、&&、||、<、>=


示例:    该为varnish默认策略中的一段,表示若请求方法为GET、HEAD则直接交由后端主机处理

        若请求包含认证或Cookie则直接交由后端主机处理

1
<span style="font-size:14px;">sub vcl_recv {<br>    ...<br>    if (req.method != "GET" && req.method != "HEAD") {<br>        /* We only deal with GET and HEAD by default */<br>        return (pass);<br>    }<br>    if (req.http.Authorization || req.http.Cookie) {<br>        /* Not cacheable by default */<br>        return (pass);<br>    }<br>    ...<br>}</span><br>




vcl state engine 状态引擎:

vcl_recv:用于接收和处理请求;当请求到达并成功接收后被调用,通过判断请求的数据来决定如何处理请求;
vcl_pipe:用于将请求直接传递至后端主机,并将后端响应原样返回客户端;
vcl_pass:用于将请求直接传递至后端主机,但后端主机的响应并不缓存直接返回客户端;
vcl_hit:在执行 lookup 指令后,在缓存中找到请求的内容后将自动调用该函数;
vcl_miss:在执行 lookup 指令后,在缓存中没有找到请求的内容时自动调用该方法,此函数可用于判断是否需要从后端服务器获取内容;
vcl_hash:在vcl_recv调用后为请求创建一个hash值时,调用此函数;此hash值将作为varnish中搜索缓存对象的key;
vcl_purge:pruge操作执行后调用此函数,可用于构建一个响应;
vcl_deliver:将在缓存中找到请求的内容发送给客户端前调用此方法;
vcl_backend_fetch:向后端主机发送请求前,调用此函数,可修改发往后端的请求;
vcl_backend_response:获得后端主机的响应后,可调用此函数;
vcl_backend_error:当从后端主机获取源文件失败时,调用此函数;
vcl_init:VCL加载时调用此函数,经常用于初始化varnish模块(VMODs)
vcl_fini:当所有请求都离开当前VCL,且当前VCL被弃用时,调用此函数,经常用于清理varnish模块;
vcl_synth:自定义返回页面,可在purge操作时调用。

主要语法:

1
2
3
4
5
6
7
8
9
sub subroutine {
...
}
if CONDITION {
...
} else {
...
}
return(), hash_data()




配置示例:


]# vi /etc/varnish/default.vcl
]# varnish_reload_vcl


后端主机健康监测:
1
probe check {        定义该检查的名称为 check ,当后端主机较多时,直接在 backend 中调用即可。
    .url = "/.healthcheck.html";
   .window = 5;    基于最近多少次探测
    .threshold = 4;  最近.window定义的检查次数中.threshhold定义的次数成功则为健康
    .interval = 2s;    检查时间间隔
    .timeout = 1s;     超时时长
    .expected_response:  期望的响应码,默认为200;





声明并初始化一个后端对象:
1
backend web1 {
   .host = "10.1.235.33";
>   .port = "80";
   .probe = check;    调用该检查机制
}
backend web2 {
   .host = "10.1.235.66";
  .port = "80";
  .probe = check;
}




清除图片类请求响应首部cookie字段,取消私有标识,并指定可缓存时长ttl (增加)
1
sub vcl_backend_response {
    if (bereq.http.cache-control !~ "s-maxage") {
        if (bereq.url ~ "(?i)\.jpg$") {        (?i) 表示不区分大小写
            set beresp.ttl = 7200s;
        unset beresp.http.Set-Cookie;
    }
        if (bereq.url ~ "(?i)\css&") {
            set beresp.ttl = 7200s;
            unset beresp.http.Set-Cookie;
        }
    }





缓存对象修剪:
        purge        自定义的方法,通常请求指定url缓存
        ban        通常用来清理表达式匹配的缓存项
1
acl purge {acl控制,定义可清理缓存的主机地址,防止用户操作
"localhost";
"10.1.235.6"/16;
}
sub vcl_recv {
if (req.method == "PURGE") {     若方法为 PURGE 则执行清理操作
if (!client.ip ~ purge) {    限制来源
return(synth(405,"Not allowed."));
}
    return (purge);    定义下一步
}
}
sub vcl_purge {
return (synth(200,"Purged."));    返回 sycth 定义的页面
}





当有多个backend:动静分离
设定多个后端主机
1
backend default {
.host = "10.1.235.66";
.port = "80"
}
backend phpsrv {
.host = "10.1.235.77";
.port = "80";
}




接收时策略,对不同类型的资源请求分发到专用的后端服务器上
1
vcl_recv {
    if (req.url ~ "(?i)\.php$") {
        set req.backend_hint = "phpsrv";
    } else {
       set req.backend_hint = "default";
    }
}





实现负载均衡:        缓存可能导致无负载均衡效果,可定义不可缓存文件或目录测试

1
import directors;    # 需先加载 directors



定义后端主机:
1
backend web1 {
    .host = "10.1.235.33";
}
backend web2 {
   .host = "10.1.235.66";
}




定义后端服务器组:
1
sub vcl_init {
>    new websrv = directors.round_robin();    round_robin|random 调度算法较少
    websrv.add_backend(web1);
    websrv.add_backend(web2);
}




分发请求时调用该组:
1
sub vcl_recv {
    # send all traffic to the bar director:
    set req.backend_hint = websrv.backend();
}







日志系统:

    varnish 默认将日志记录在一段共享内存中 shared memory log ,内存空间分为两部分,计数器和日志信息,提供非常详细的信息,这提高了性能,但不易于查找问题,记录在内存中的数据无法长时间保存。
    内存中日志区域大小有限,如果不使用一个程序将日志信息保存到磁盘上,日志数据将会被不断覆盖。


日志查看命令:

]# varnishlog    动态持续更新显示日志信息

]# varnishtop    对日志信息做了整理排序
        -1 仅输出一次静态信息后退出    数字 1
        -i taglist,可以同时使用多个-i选项,也可以一个选项跟上多个标签;
        -I <[taglist:]regex>
        -x taglist:排除列表
        -X <[taglist:]regex>

]# varnishstat    缓存状态查看
        -1 -f FILED_NAME
        -l:可用于-f选项指定的字段名称列表;

日志记录服务:
varnishlog    以varnishlog命令输出的格式记录日记,内容较多,不易读

varnishncsa    以类似http访问日志格式记录日志,combined 日志格式

一般可开启 varnishncsa 服务将日志记录于磁盘上

1
]# service varnishncsa start



    默认保存于 /var/log/varnish/varnishncsa.log





运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-298761-1-1.html 上篇帖子: CentOS 7.x自定义开机启动设置 下篇帖子: varnish缓存实现动静分离
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表