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

[经验分享] Linux之varnish

[复制链接]

尚未签到

发表于 2018-5-23 12:52:32 | 显示全部楼层 |阅读模式
  一:varnish简介
  Varnish是一款高性能的开源HTTP加速器,挪威最大的在线报纸 Verdens Gang 使用3台Varnish代替了原来的12台Squid,性能比以前更好
      Varnish 的作者Poul-Henning Kamp是FreeBSD的内核开发者之一,他认为现在的计算机比起1975年已经复杂许多。在1975年时,储存媒介只有两种:内存与硬盘。但现在计算机系统的内存除了主存外,还包括了CPU内的L1、L2,甚至有L3快取。硬盘上也有自己的快取装置,因此Squid Cache自行处理物件替换的架构不可能得知这些情况而做到最佳化,但操作系统可以得知这些情况,所以这部份的工作应该交给操作系统处理,这就是 Varnish cache设计架构.
   二:varnish设计机构图
DSC0000.jpg

  



[size=1.16em]   
  

三:VCL 处理流程
  
DSC0001.jpg

Varnish 处理 HTTP 请求的过程大致分为如下几个步骤。
      - Receive 状态(vcl_recv)。也就是请求处理的入口状态,根据 VCL 规则判断该请求应该 pass(vcl_pass)或是 pipe(vcl_pipe),还是进入 lookup(本地查询)。
      - Lookup 状态。进入该状态后,会在 hash 表中查找数据,若找到,则进入 hit(vcl_hit)状态,否则进入 miss(vcl_miss)状态。
      - Pass(vcl_pass)状态。在此状态下,会直接进入后端请求,即进入 fetch(vcl_fetch)状态
      - Fetch(vcl_fetch)状态。在 fetch 状态下,对请求进行后端获取,发送请求,获得数据,并根据设置进行本地存储。
      - Deliver(vcl_deliver)状态。将获取到的数据发给客户端,然后完成本次请求
  
[size=1.16em]
[size=1.16em]
1) VCL 内置函数
[size=1.16em]
vcl_recv 函数
   用于接收和处理请求。当请求到达并成功接收后被调用,通过判断请求的数据来决定如何处理请求。例如如何响应、怎么响应、使用哪个后端服务器等。
   此函数一般以如下几个关键字结束。
pass:表示进入 pass 模式,把请求控制权交给 vcl_pass 函数。
pipe:表示进入 pipe 模式,把请求控制权交给 vcl_pipe 函数。
lookup:表示进入 lookup 模式,把请求控制权交给 lookup 指令处理,在缓存中查找被请求的对象,并且根据查找的结果把控制权交给函数 vcl_hit 或函数 vcl_miss。
error code [reason]:表示返回“code”给客户端,并放弃处理该请求。“code”是错误标识,例如 200 和 405 等。“reason”是错误提示信息.


vcl_pipe 函数
   此函数在进入 pipe 模式时被调用,用于将请求直接传递至后端主机,在请求和返回的内容没有改变的情况下,将不变的内容返回给客户端,直到这个连接被关闭。
此函数一般以如下几个关键字结束。
error code [reason]。
pipe

  

vcl_pass 函数
   此函数在进入 pass 模式时被调用,用于将请求直接传递至后端主机。后端主机在应答数据后将应答数据发送给客户端,但不进行任何缓存,在当前连接下每次都返回最新的内容。
此函数一般以如下几个关键字结束。
error code [reason]。
pass。
restart 重新启动流程,增加启动次数,如果重新启动次数高于 max_restarts 发出一个错误警告
  

[size=1.16em]vcl_hash
[size=1.16em]   当您想把一个数据添加到 hash 上时,调用此函数。
[size=1.16em]   此函数一般以如下几个关键字结束
[size=1.16em]vcl_hit 函数
[size=1.16em]   在执行 lookup 指令后,在缓存中找到请求的内容后将自动调用该函数。
[size=1.16em]此函数一般以如下几个关键字结束。
[size=1.16em]deliver:表示将找到的内容发送给客户端,并把控制权交给函数 vcl_deliver。
[size=1.16em]error code [reason] 。
[size=1.16em]pass。
[size=1.16em]restart 重新启动流程,增加启动次数,如果重新启动次数高于 max_restarts 发出一个错误警告
[size=1.16em]

[size=1.16em]  vcl_miss 函数
[size=1.16em]  在执行 lookup 指令后,在缓存中没有找到请求的内容时自动调用该方法。此函数可用于判断是否需要从后端服务器获取内容。
[size=1.16em]此函数一般以如下几个关键字结束。
[size=1.16em]fetch:表示从后端获取请求的内容,并把控制权交给 vcl_fetch 函数。
[size=1.16em]error code [reason] 。
[size=1.16em]pass。
[size=1.16em]

[size=1.16em]
vcl_fetch 函数
  在后端主机更新缓存并且获取内容后调用该方法,接着,通过判断获取的内容来决定是将内容放入缓存,还是直接返回给客户端。
此函数一般以如下几个关键字结束。
error code [reason]。
pass。
deliver。
esi。
restart 重新启动流程,增加启动次数,如果重新启动次数高于 max_restarts 发出一个错误警告


vcl_deliver 函数
  将在缓存中找到请求的内容发送给客户端前调用此方法。
此函数一般以如下几个关键字结束。
error code [reason]。
deliver。
restart 重新启动流程,增加启动次数,如果重新启动次数高于 max_restarts 发出一个错误警告
vcl_error
出现错误时调用此函数。
此函数一般以如下几个关键字结束。
deliver。
restart
[size=1.16em]

[size=1.16em]2)工作流程概述
[size=1.16em]   Varnish 与一般服务器软件类似,分为 master 进程和 child 进程。Master 进程读入存储配置文件,调用合适的存储类型,然后创建 / 读入相应大小的缓存文件,接着 master 初始化管理该存储空间的结构体,然后 fork 并监控 child 进程。Child 进程在主线程的初始化的过程中,将前面打开的存储文件整个 mmap 到内存中,此时创建并初始化空闲结构体,挂到存储管理结构体,以待分配。Child 进程分配若干线程进行工作,主要包括一些管理线程和很多 worker 线程。
[size=1.16em]    接着,开始真正的工作,varnish 的某个负责接收新 HTTP 连接线程开始等待用户,如果有新的 HTTP 连接过来,它总负责接收,然后唤醒某个等待中的线程,并把具体的处理过程交给它。Worker 线程读入 HTTP 请求的 URI计算出响应的hash值,查找已有的 object,如果命中则直接返回并回复用户。如果没有命中,则需要将所请求的内容,从后端服务器中取过来,存到缓存中,然后再回复。
[size=1.16em]   分配缓存的过程是这样的:它根据所读到 object 的大小,创建相应大小的缓存文件。为了读写方便,程序会把每个 object 的大小变为最接近其大小的内存页面倍数。然后从现有的空闲存储结构体中查找,找到最合适的大小的空闲存储块,分配给它。如果空闲块没有用完,就把多余的内存另外组成一个空闲存储块,挂到管理结构体上,这样做可以减少磁盘碎片。如果缓存已满,就根据 LRU(最近做少使用原则) 机制,把最旧的 object 释放掉。
[size=1.16em]   释放缓存的过程是这样的:有一个超时线程,检测缓存中所有 object 的生存期,如果超初设定的 TTL(Time To Live)没有被访问,就删除之,并且释放相应的结构体及存储内存。注意释放时会检查该存储内存块前面或后面的空闲内存块,如果前面或后面的空闲内存和该释放内存是连续的,就将它们合并成更大一块内存。
[size=1.16em]    整个文件缓存的管理,没有考虑文件与内存的关系,实际上是将所有的 object 都考虑是在内存中,如果系统内存不足,系统会自动将其换到 swap 空间,而不需要 varnish 程序去控制。
  四:VCL的内置公共变量
   1)当请求到达时,可以使用的公共变量
  
DSC0002.jpg

  2)对客户端相应时可使用公共变量
  
DSC0003.jpg

  3)后端主机获取内容时可使用公共变量
DSC0004.jpg

  五:varnish试验
  1)试验拓扑
  
DSC0005.jpg

  

  2)查看安装的配置文件
[root@varnish ~]# rpm -ql varnish
/etc/logrotate.d/varnish
/etc/rc.d/init.d/varnish #启动脚本
/etc/rc.d/init.d/varnishlog
/etc/rc.d/init.d/varnishncsa
/etc/sysconfig/varnish #启动脚本的配置文件
/etc/varnish #全局配置文件
/etc/varnish/default.vcl #默认VCL
/usr/bin/varnish_reload_vcl #varnish管理工具
/usr/bin/varnishadm
/usr/bin/varnishhist
/usr/bin/varnishlog
/usr/bin/varnishncsa
/usr/bin/varnishreplay
/usr/bin/varnishsizes
/usr/bin/varnishstat
/usr/bin/varnishtest
/usr/bin/varnishtop
/usr/lib64/varnish
/usr/lib64/varnish/libvarnish.so
/usr/lib64/varnish/libvarnishcompat.so
/usr/lib64/varnish/libvcl.so
/usr/lib64/varnish/libvgz.so
/usr/lib64/varnish/vmods
/usr/lib64/varnish/vmods/libvmod_std.so
/usr/sbin/varnishd
/usr/share/doc/varnish-3.0.4
/usr/share/doc/varnish-3.0.4/ChangeLog
/usr/share/doc/varnish-3.0.4/LICENSE
/usr/share/doc/varnish-3.0.4/README
/usr/share/doc/varnish-3.0.4/README.redhat
/usr/share/doc/varnish-3.0.4/examples
/usr/share/doc/varnish-3.0.4/examples/default.vcl
/usr/share/doc/varnish-3.0.4/examples/zope-plone.vcl
/usr/share/man/man1/varnishadm.1.gz #man配置文件
/usr/share/man/man1/varnishd.1.gz
/usr/share/man/man1/varnishhist.1.gz
/usr/share/man/man1/varnishlog.1.gz
/usr/share/man/man1/varnishncsa.1.gz
/usr/share/man/man1/varnishreplay.1.gz
/usr/share/man/man1/varnishsizes.1.gz
/usr/share/man/man1/varnishstat.1.gz
/usr/share/man/man1/varnishtest.1.gz
/usr/share/man/man1/varnishtop.1.gz
/usr/share/man/man3/vmod_std.3.gz
/usr/share/man/man7/varnish-cli.7.gz
/usr/share/man/man7/varnish-counters.7.gz
/usr/share/man/man7/vcl.7.gz
/var/lib/varnish
/var/log/varnish #日志文件  3)修改启动脚本配置文件
[root@varnish sysconfig]# vim /etc/sysconfig/varnish
VARNISH_LISTEN_PORT=80 #这里设置的监听端口设置为80
VARNISH_STORAGE="malloc,64M" #我们这里设置的是64M,因为我们这里是测试环境,在生产环境中可以根据实际需求设置很大  4)启动varnish

[root@varnish ~]# service varnish start
Starting Varnish Cache:                  [确定]  5)配置后端http服务器

[root@web1 ~]# yum install -y httpd
[root@web1 ~]# cat /var/www/html/index.html
<h1>varnish server node1</h1>
[root@web1 ~]# service httpd start
正在启动 httpd:  6)真假vcl配置文件

[root@varnish ~]# cd /etc/varnish/
[root@varnish varnish]# cp default.vcl test.vcl
[root@varnish varnish]# vim test.vcl
backend webserver {
.host = "172.16.16.1";
.port = "80";
}
sub vcl_recv {
set req.backend = webserver;
}  7)加载vcl配置文件

[root@varnish ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
200
-----------------------------
Varnish Cache CLI 1.0
-----------------------------
Linux,2.6.32-358.el6.x86_64,x86_64,-smalloc,-smalloc,-hcritbit
varnish-3.0.4 revision 9f83e8f
Type 'help' for command list.
Type 'quit' to close CLI session.
varnish> vcl.load test test.vcl #编译
200
VCL compiled.
varnish> vcl.list
200
active     0 boot
available    0 test
varnish> vcl.use test
200  OK,进行测试一下

DSC0006.jpg

  

  如何修改配置文件查看我们的缓存是否命中

  1)修改配置文件
[root@varnish varnish]# vim test.vcl
backend default {
.host = "172.16.16.1";
.port = "80";
}
sub vcl_recv {
set req.backend = webserver;
}
#修改vcl_deliver增一个响应头部
sub vcl_deliver {
     if (obj.hits > 0) {
        set resp.http.X-Cache = "Hit from"+" "+server.ip;
    } else {
        set resp.http.X-Cache = "Miss via"+" "+server.ip;
    }
}
DSC0007.jpg

  第一次加载时缓存X-Cache为Miss(没有被命中).

DSC0008.jpg

  第二次刷新加载时命中缓存此处的X-Cache为HIT.
  如何设置让某个条件不被命中
  1)修改配置文件
[root@varnish ~]# vim /etc/varnish/test.vcl
backend webserver {
    .host = "172.16.16.1";
    .port = "80";
}
#设置条件让请求test.html文件时不缓存
sub vcl_recv {
    if (req.url ~ "^/test.html$") {
        return(pass);
    }
    set req.backend = webserver;
}
sub vcl_deliver {
     if (obj.hits > 0) {
        set resp.http.X-Cache = "Hit from"+" "+server.ip;
    } else {
        set resp.http.X-Cache = "Miss via"+" "+server.ip;
    }
}
[root@web1 ~]# vim /var/www/html/test.html
<h1>mandela</h1>  2)重新加载配置文件

varnish> vcl.load test2 test.vcl
200
VCL compiled.
varnish> vcl.use test2
200
DSC0009.jpg

  

  不管刷新多少次始终是不会对此网页信息进行缓存.

  如何根据响应内容作出判断

  修改配置文件
[root@varnish ~]# vim /etc/varnish/test.vcl
backend webserver {
    .host = "172.16.16.1";
    .port = "80";
}
sub vcl_recv {
    if (req.url ~ "^/test.html$") {
        return(pass);
    }
    set req.backend = webserver;
}
sub vcl_fetch {
    if (req.request == "GET" && req.url ~ "\.(html|css|js|jpg|jpeg|png|gif)$") {
        set beresp.ttl = 3600s;
    }
}
sub vcl_deliver {
     if (obj.hits > 0) {
        set resp.http.X-Cache = "Hit from"+" "+server.ip;
    } else {
        set resp.http.X-Cache = "Miss via"+" "+server.ip;
    }
}  重新加载文件
varnish> vcl.load test3 test.vcl
200
VCL compiled.
varnish> vcl.use test3
200  varnish如何实现负载均衡及检查后端主机状态
  修改配置文件

[root@varnish ~]# vim /etc/varnish/test.vcl
backend webserver1 {
    .host = "172.16.16.1";
    .port = "80";
    .probe = {
    .url = "/index.html";
    .interval = 1s;
    .window = 3;
    .threshold = 1;
  }
}
backend webserver2 {
    .host = "172.16.16.4";
    .port = "80";
    .probe = {
    .url = "/index.html";
    .interval = 1s;
    .window = 3;
    .threshold = 1;
  }
}
director webserver random {
    { .backend = webserver1; .weight = 3; }
    { .backend = webserver2; .weight = 1; }
}
sub vcl_recv {
      set req.backend = webserver;
}
sub vcl_deliver {
     if (obj.hits > 0) {
        set resp.http.X-Cache = "Hit from"+" "+server.ip;
    } else {
        set resp.http.X-Cache = "Miss via"+" "+server.ip;
    }
}  重新装载
varnish> vcl.load test4 test.vcl
200
VCL compiled.
varnish> vcl.use test4
200  这样后端定义了两个主机16.1和16.2.且实现了轮训调度加缓存机制加后段的安全状态检测,后端的安全状态检测是每一秒检测一次,检测三次不在线就自动下线.判断在线次数只需要判断一次.

varnish> backend.list
200        
Backend name                   Refs   Admin      Probe
default(127.0.0.1,,80)         1      probe      Healthy (no probe)
webserver(172.16.16.1,,80)     4      probe      Healthy (no probe)
webserver1(172.16.16.1,,80)    3      probe      Healthy 3/3
webserver2(172.16.16.4,,80)    3      probe      Healthy 3/3  定义的后端主机分别是16.1和16.4
DSC00010.jpg

  每隔一秒钟就检测一下后端主机是否在线.200状态码说明主机在线.
  OK 我们的varnish配置基本完成.希望大家有些收获.

运维网声明 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-480374-1-1.html 上篇帖子: LINUX下安装Quagga 下篇帖子: linux小知识系列
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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