一、什么是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结构
(一)、两种进程:
① 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> lsdrwxr-xr-x 2 0 0 4096 Jan 07 09:18 3.0.4drwxr-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.rpmlftp 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%]
生成文件相关说明:
[[email protected] ~]# 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_max和thread_pool_timeout实时参数值的捷径。如果只给定了一个数值,则表示min和max都是这个值,且timeout是无效的。
51cto抽风