一、什么是varnish

 

       Varnish 是一款高性能且开源的反向代理服务器和 HTTP 加速器,其采用全新的软件体系机构,和现在的硬件体系紧密配合,与传统的 squid 相比,varnish 具有性能更高、速度更快、管理更加方便等诸多优点。

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

       接着,开始真正的工作,varnish 的某个负责接收新 HTTP 连接线程开始等待用户,如果有新的 HTTP 连接过来,它总负责接收,然后唤醒某个等待中的线程,并把具体的处理过程交给它。Worker 线程读入 HTTP 请求的 URI,查找已有的 object,如果命中则直接返回并回复用户。如果没有命中,则需要将所请求的内容,从后端服务器中取过来,存到缓存中,然后再回复。

       分配缓存的过程是这样的:它根据所读到 object 的大小,创建相应大小的缓存文件。为了读写方便,程序会把每个 object 的大小变为最接近其大小的内存页面倍数。然后从现有的空闲存储结构体中查找,找到最合适的大小的空闲存储块,分配给它。如果空闲块没有用完,就把多余的内 存另外组成一个空闲存储块,挂到管理结构体上。如果缓存已满,就根据 LRU 机制,把最旧的 object 释放掉。

       释放缓存的过程是这样的:有一个超时线程,检测缓存中所有 object 的生存期,如果超初设定的 TTL(Time To Live)没有被访问,就删除之,并且释放相应的结构体及存储内存。注意释放时会检查该存储内存块前面或后面的空闲内存块,如果前面或后面的空闲内存和该 释放内存是连续的,就将它们合并成更大一块内存。

       整个文件缓存的管理,没有考虑文件与内存的关系,实际上是将所有的 object 都考虑是在内存中,如果系统内存不足,系统会自动将其换到 swap 空间,而不需要 varnish 程序去控制。

 

二、varnish结构

 

wKioL1V0OLawf2tOAAE0eBrhUNc968.jpg

 

(一)、两种进程:

 

     ① management主进程

         编译VCL并应用新配置、监控varnish(如果发现某个子进程不正常或不在工作,则会重启该进程)、初始化varnish,并提供一个CLI;

         三个管理接口:

            cli if

            telnet if

            web if :收费

     ② Child/Cache线程,有下面几类:

           Acceptor:接收新的连接请求;

           Worker:用于处理并响应用户请求;

           Expiry:从缓存中清理过期cache object

 

(二)日志:

 

         logfile:在内存中找一段固定大小的片段记录,满后就从头开始记录,因此如果需要永久保存就需要定期导出。

        malloc:使用 shared memry log,工作于内存中,性能优越,共享内存日志,日志大小一般90M(与版本有关):分两部分——前一部分为计数器,后一部分为客户请求相关的数据;

 

(三)11种状态引擎state engine:

 

       vcl配置的缓存策略在这些state engine中发挥作用,state engine之间有相关性,上级engine通过return指明下级engine;如果子程序中没有设定或者后续引擎没有指定,则控制器会采用默认设置;

         vcl的配置语法:

             (1) //, #, /*comment*/用于注释;

             (2) sub $NAME 用于定义函数(不支持参数,更像过程,执行完就没了);

             (3) 不支持循环;

             (4) 有众多内置变量;

             (5) 支持终止语句(return),没有返回值;

             (6) “域”专用语言(代码必须写在特定相关域中);

             (7) 操作符:  =(赋值),==(比较),~(模式匹配),!(取反),&&(逻辑与),||(逻辑或)

①vcl_recv

          请求被接入,但在其被分析、处理之前调用,目的是 决定是否服务此请求、如何处服务、使用哪个后端服务器响应。

          结束时可用 returm()关键字:

          error code[reason]

                返回特定的错误码给客户端,然后丢弃此请求

          pass

                 调用vcl_pass引擎,切换到pass模式

          pipe

                切换至pipe模式,最终是交给vcl_pipe处理

          lookup

                交换给hash查找缓存对象

②vcl_pipe:

           varnish缓存服务器直接将客户端请求交给后端服务器处理,自己不任何处理,后端服务器的响应也是不做处理直接给客户端,此客户端的后续数据报文也做此处理,直到客户端或者后端服务器中任何一方断开连接为止。

          结束时可用 returm()关键字:

          error code [reason]

                返回特定的错误码给客户端,然后丢弃此请求

          pipe

                交给pipe模式处理

③vcl_pass:

           将客户端请求传送给后端服务器,后端服务器响应的报文不存入缓存而传给客户端

          通过下面的returm()关键字结束vcl_pass:

          error code [reason]

               返回特定的错误码给客户端,然后丢弃此请求

          pass

                调用vcl_pass引擎,切换到pass模式

④vcl_hash:调用hash_data()查找缓存

          通过调用returm(hash)继续进行下一步

⑤vcl_hit:

         当在缓存中成功找到时调用

          通过调用下面的returm()来结束:

          deliver

                切换至vcl_deliver引擎,将找到的内容发送给客户

          error code [reason]

                返回特定的错误码给客户端,然后丢弃此请求

          pass

                调用vcl_pass引擎,切换到pass模式

          restart

                重启会话,这会增加restart计数器的值,当该值大于max_restarts ,varnish会报错并终止会话

 ⑥vcl_miss:

         当在缓存中没有找到对应的对象时调用;在此域中设置是否要到后端服务器去取数据,及使用哪台后端服务器

          通过调用下面的returm()来结束:

          error code [reason]

                返回特定的错误码给客户端,然后丢弃此请求

          pass

                调用vcl_pass引擎,切换到pass模式

          fetch

                调用 vcl_fetch引擎到后端服务器去数据

⑦vcl_fetch:

          当成功从后端服务器取到数据时调用

          通过调用下面的returm()来结束:

          deliver

                切换至vcl_deliver引擎,将找到的内容发送给客户

          error code [reason]

                返回特定的错误码给客户端,然后丢弃此请求

          hit_for_pass

                pass此模式,产生一个hit_for_pass object

          restart

                重启会话,这会增加restart计数器的值,当该值大于max_restarts ,varnish会报错并终止会话

⑧vcl_delier:

         在构建响应报文返回给客户端时调用

          通过调用下面的returm()来结束:

          deliver

                切换至vcl_deliver引擎,将找到的内容发送给客户

          restart

                重启会话,这会增加restart计数器的值,当该值大于max_restarts ,varnish会报错并终止会话

⑨vcl_error:

         当发生错误时调用;错误无论大小,无论是varnish引擎自己产生的还是后端服务器的错误

          通过调用下面的returm()来结束:

          deliver

                切换至vcl_deliver引擎,将找到的内容发送给客户

          restart

                重启会话,这会增加restart计数器的值,当该值大于max_restarts ,varnish会报错并终止会话

⑩vcl_init:

         初始化引擎,当vcl刚装载还没有任何请求被通过时使用,装载不同的模块(VMODS)时使用

          可使用的returm()值

          ok

                正常返回,继续装载其他引擎

 vcl_fini:

          仅在处理完所有请求后需要丢弃某个vcl策略时调用

          通过调用下面的returm()来结束:

           ok

                 正常返回,不调用其他引起,vcl策略将被删除

 

 

 

 

三、安装varnish及生成文件相关说明

    在教室环境中lftp下载程序包并安装:

lftp 172.16.0.1:/pub/Sources/6.x86_64> cd varnish/
lftp 172.16.0.1:/pub/Sources/6.x86_64/varnish> ls
drwxr-xr-x    2 0        0            4096 Jan 07 09:18 3.0.4
drwxr-xr-x    2 500      500          4096 Sep 24  2014 3.0.5
-rw-r--r--    1 0        0          454496 Oct 21  2014 varnish-3.0.6-1.el6.x86_64.rpm
-rw-r--r--    1 0        0          360284 Oct 21  2014 varnish-docs-3.0.6-1.el6.x86_64.rpm
-rw-r--r--    1 0        0           42620 Oct 21  2014 varnish-libs-3.0.6-1.el6.x86_64.rpm
-rw-r--r--    1 0        0           23992 Oct 21  2014 varnish-libs-devel-3.0.6-1.el6.x86_64.rpm
lftp 172.16.0.1:/pub/Sources/6.x86_64/varnish> mget *.rpm



# rpm -ivh varnish-libs-3.0.6-1.el6.x86_64.rpm varnish-3.0.6-1.el6.x86_64.rpm varnish-docs-3.0.6-1.el6.x86_64.rpm 
Preparing...                ########################################### [100%]
   1:varnish-libs           ########################################### [ 33%]
   2:varnish                ########################################### [ 67%]
   3:varnish-docs           ########################################### [100%]


 生成文件相关说明:

[root@aunt-s ~]# rpm -pql varnish-3.0.6-1.el6.x86_64.rpm 
/etc/logrotate.d/varnish   ——设定日志滚动记录的脚本
/etc/rc.d/init.d/varnish ——varnish程序服务脚本
/etc/rc.d/init.d/varnishlog ——控制varnish日志守护进程服务脚本
/etc/rc.d/init.d/varnishncsa ——控制varnish NCSA日志记录守护进程服务脚本
上面两种日志都是从共享内存日志中抽取数据永久记录日志的,只是记录的格式不同,启动其中一个即可。
/etc/sysconfig/varnish ——配置varnish自己的工作特性(如监听地址和端口),通过向/etc/rc.d/init.d/varnish传递参数配置实现的。
/etc/varnish
/etc/varnish/default.vcl ——配置缓存策略文件
/usr/bin/varnish_reload_vcl
/usr/bin/varnishadm ——varnish的CLI
/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 ——varnish主程序
/usr/share/doc/varnish-3.0.6
/usr/share/doc/varnish-3.0.6/ChangeLog
/usr/share/doc/varnish-3.0.6/LICENSE
/usr/share/doc/varnish-3.0.6/README
/usr/share/doc/varnish-3.0.6/README.redhat
/usr/share/doc/varnish-3.0.6/examples
/usr/share/doc/varnish-3.0.6/examples/default.vcl
/usr/share/doc/varnish-3.0.6/examples/zope-plone.vcl
/usr/share/man/man1/varnishadm.1.gz
/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 ——日志记录目录

 

varnish-docs-3.0.6-1.el6.x86_64.rpm此程序包提供varnish帮助文档,文件格式是html,不是必须安装程序。

 

四、CLI管理工具

(一)varnishadm

定义varnish工作特性的命令:

varnishd

格式:

varnishd [-a address[:port]] [-b host[:port]] [-d] [-F] [-f config]

 

option:

 1-a address[:port][,address[:port][...]

监听的地址和端口,地址可以是主机名(如“localhost”)、IPv4地址(如“127.0.0.1”)、IPv6地址(如“[::1]”),未指定则监听所有可用的IP地址

端口未指定则监听/etc/services 文件指定的HTTP服务端口(一般是80)

2-b host[:port]

          指定后端服务器及端口。如果端口未指定,则默认是8080.一般在配置文件中做精细指定,而不在这指定。

3-C

直接显示vcl编译后的代码转换为C语言,然后退出。

4-d     

打开调试模式:主进程通过CLI接口运行于前台,子进程须通过CLI命令启动,关闭主进程也会终止子进程

5-F

让守护进程运行于前台

6 -f config

通过指定的VCL配置文件传递规则给varnish守护进程,以代替默认的内置规则。如果没有设置配置参数,varnish进程不会启动。

7-g group

指定子进程以什么组身份运行的

     8-h type[,options]

指明hash算法,可以指定的 hash算法类型:

  simple_list

指明一个简单的双链表,自左而右支持多种。不推荐生产使用 

   classic[,buckets]

标准hash表,默认选项。hash的键是对目标url做hash得到的。buckets是指定进入hash表的入口数,默认是16383.

 critbit

         很少用。自我缩放的树结构hash算法

9-i identity

指明varnish服务器标识符,意义不大

10-l shmlogsize

指明共享内存日志文件大小,默认80MB(版本不一样,默认大小可能不同),小于8MB是不明智的

 

11-n name

指明进程名字,保存进程临时文件和持续状态时的路径会使用此名字。名字如果以“/”开头,则是使用绝对路径创建文件  

12-P file

指名pid文件              Write the process's PID to the specified file.

 

13-p param=value

指定参数值  

14       -S file

指定授权进入管理端口的密钥文件              Path to a file containing a secret used for authorizing access to the management port.

15-s [name=]type[,options]

使用制定的存储后端(是内存还是单个文件)。存储后端可以指定多个,记录日志及统计信息时也以此后端为标签。  

可用的存储类型Storage Types

 malloc[,size]

这表面在内存中缓存,size指明使用缓存的最大值,单位为字节,可用K、k、M、m、G、g、T、t单位。如果未给定size,则没有上限。

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

使用单个文件构建缓存,所有缓存对象都存储在这个文件中,存储类型的默认选项。

path指明该文件的路径(默认是/tmp),size指明大小,默认为字节,可用K、k、M、m、G、g、T、t单位  ,也可用%指明使用所在分区的空闲空间的百分比,默认是50%

 persistent,path,size {experimental}

实验型存储类型,生产中莫用。存储对象存储于单个文件中,进程重启后不会消失。           path指明该文件路径,,size指明大小,单位为字节,可用K、k、M、m、G、g、T、t单位。

            

16-T address[:port]

指定管理接口的监听地址和端口,端口默认是6082  

17-t ttl 

指定缓存文件的ttl值(time to live)

18 -w min[,max[,timeout]]

指定启动时的最少及最大子进程数、空闲进程的超时时长。 这个是指定 thread_pool_min,  thread_pool_maxthread_pool_timeout实时参数值的捷径。如果只给定了一个数值,则表示min和max都是这个值,且timeout是无效的。

 

 

 

 51cto抽风