varnish
简介 | 安装 | 工作流程 | VCL介绍 | 日志系统
简介:
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/releases/install_redhat.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"
以指定最大空闲线程数、最大线程数、线程超时时长等。
... # # 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停止或重启时会清除数据。
设计结构:
工作流程:
Varnish 与一般服务器软件类似,分为 master 进程和 child 进程。Master 进程读入存储配置文件,调用合适的存储类型,然后创建 / 读入相应大小的缓存文件,接着 master 初始化管理该存储空间的结构体,然后 fork 并监控 child 进程。Child 进程分配若干线程进行工作,主要包括一些管理线程和很多 worker 线程。
Varnish 的某个负责接收新 HTTP 连接线程开始等待用户,如果有新的 HTTP 连接过来,它总负责接收,然后唤醒某个等待中的线程,并把具体的处理过程交给它。Worker 线程读入 HTTP 请求的 URI,查找已有的 object,如果命中则直接返回并回复用户。如果没有命中,则需要将所请求的内容,从后端服务器中取过来,存到缓存中,然后再回复。具体决策操作流程由vcl各状态引擎实现
配置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则直接交由后端主机处理
sub vcl_recv {
...
if (req.method != "GET" && req.method != "HEAD") {
/* We only deal with GET and HEAD by default */
return (pass);
}
if (req.http.Authorization || req.http.Cookie) {
/* Not cacheable by default */
return (pass);
}
...
}
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操作时调用。
主要语法:
sub subroutine { ... } if CONDITION { ... } else { ... } return(), hash_data()
配置示例:
]# vi /etc/varnish/default.vcl
]# varnish_reload_vcl
后端主机健康监测:
probe check { 定义该检查的名称为 check ,当后端主机较多时,直接在 backend 中调用即可。
.url = "/.healthcheck.html";
.window = 5; 基于最近多少次探测
.threshold = 4; 最近.window定义的检查次数中.threshhold定义的次数成功则为健康
.interval = 2s; 检查时间间隔
.timeout = 1s; 超时时长
.expected_response: 期望的响应码,默认为200;
}
声明并初始化一个后端对象:
backend web1 {
.host = "10.1.235.33";
.port = "80";
.probe = check; 调用该检查机制
}
backend web2 {
.host = "10.1.235.66";
.port = "80";
.probe = check;
}
清除图片类请求响应首部cookie字段,取消私有标识,并指定可缓存时长ttl (增加)
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 通常用来清理表达式匹配的缓存项
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:动静分离
设定多个后端主机
backend default {
.host = "10.1.235.66";
.port = "80"
}
backend phpsrv {
.host = "10.1.235.77";
.port = "80";
}
接收时策略,对不同类型的资源请求分发到专用的后端服务器上
vcl_recv {
if (req.url ~ "(?i)\.php$") {
set req.backend_hint = "phpsrv";
} else {
set req.backend_hint = "default";
}
}
实现负载均衡: 缓存可能导致无负载均衡效果,可定义不可缓存文件或目录测试
import directors; # 需先加载 directors
定义后端主机:
backend web1 {
.host = "10.1.235.33";
}
backend web2 {
.host = "10.1.235.66";
}
定义后端服务器组:
sub vcl_init {
new websrv = directors.round_robin(); round_robin|random 调度算法较少
websrv.add_backend(web1);
websrv.add_backend(web2);
}
分发请求时调用该组:
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 服务将日志记录于磁盘上
]# service varnishncsa start
默认保存于 /var/log/varnish/varnishncsa.log