一 varnish 简介
varnish 是一款高性能的开源的HTTP加速器,采用了“VisualPage Cache”技术,被安装在web应用程序前面,缓存web应用程序,并响应用户请求,varnish 让您的web应用程序运行的更快,并且varnish 具有更加灵活,效率更高,资源占用的更少等优点。
varinish 特点
1 是基于内存缓存,重启数据将消失
2 利用虚拟内存方式,IO性能好
3 VCL 配置管理比较灵活
4 32 为系统上缓存文件大小为2G
5 具有更强大的管理功能,
6 具有强大的管理功能,例如varnishtop,varnishstat,varnishadmin等
7 利用二交叉堆管理缓存文件,达到积极删除目的
varnish的storage 方式可分为两种:
1 malloc 通过malloc 获取内存
2 mmap file 创建大文件,通过二分法分段映射成1G以内的大块。
varnish 进程的工作模式:
varnish 启动或者有2个进程master(managemment)进程和child(worker)进程。master 读入存储配置命令,进行初始化,然后fork,监控child。child则分配线程进行cache工作,child还会做管理线程和生成很多worker线程。
child 进程主线程初始化过程中,将存储大文件整个加载到内存中,如果该文件中超出系统的虚拟内存,则会减少原来配置mmap 大小,然后继续加载,这个时候创建并初始化空闲存储结构体,放在存储管理的struct中,等待分配
接着varnish某个负责接口新http连接开始等待用户,如果有新的http连接,但是这个线程只负责接收,然后幻想等待线程池中的work线程,进行请求处理。
worker线程读入uri后,将会查找已有的object,命中直接返回,没有命中,则会从后端服务器中取出来,放到缓存中。如果缓存已满,会更加LRU算法,释放旧的object。对于释放缓存,有一个超时线程会检测缓存中所有的object的生命周期,如果缓存过期(ttl),则会删除,是否相应的存储内存。
varnish工作流程:
主进程fork 子进程,主进程等待子进程的信号,子进程退出后,主进程重新启动子进程,子进程生成若干线程
Accept线程:接收请求后,组织成session结构,看是否空闲的工作线程,如果有,将请求给它,如果overflow 过大,则放弃该请求,否则,将其挂在overflow 上
Work线程:从overflow队列上摘取请求(structses),进入状态处理过程,处理结束后,通过pipe通信,将struct ses 发送给epoll线程
Epoll 线程:将一个请求处理称作一个session,在session 周期内,处理完请求后,会交给epoll处理,若还没有过期,将socket放入epoll的事件中,事件发生时,也会将其放入overflow中
Expire线程:对于缓存的对象,根据过期时间,组织成二交叉堆,该线程周期检查该堆的根,处理过期的文件。
二 varnish 内置函数
1 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”是错误提示信息
2 vcl_pipe 函数
此函数在进入pipe 模式时被调用,用于将请求直接传递至后端主机,在请求和返回的内容没有改变的情况下,将不变的内容返回给客户端,知道这个连接被关闭。
此函数一般以如下几个关键字结束
error code [reason]
pass
restart 重新启动流程,增加启动次数,如果重新启动次数高于max_restart 发出一个错误警告
3 vcl_hash
当您想把一个数据添加到hash 上时,调用此函数
4 vcl_hit
在执行lookup 指令后,在缓存中找到请求的内容后将自动调用该函数。
此函数一般以如下几个关键字结束。
deliver:表示将找到的内容发送个客户端,并把控制权交给函数vcl_deliver。
error code [reason]
pass
restart 重启启动流程,增加启动次数,如果重新启动次数高于max_restart 发出一个错误警告
5 vcl_miss 函数
在执行lookup 指令后,在缓存中没哟找到请求的内容时自动调用该方法。此函数可用于判断是否需要冲后端服务器获取内容,此函数一般以如下几个关键字结束
fetch:表示从后端获取请求的内容,并把控制权交给vcl_fetch函数
error code [reason]
pass
6 vcl_fetch函数
在后端主机更新缓存并且获取内容后调用该方法,接着,通过判断获取的内容来决定是将内容放入缓存,还是直接返回给客户端。
如此函数一般以如下几个关键字结束
error code [reason]
pass
deliver
esi
restart 重新启动流程,增加启动次数,如果重新启动次数高于max_restart ,发出一个错误警告
7 vcl_deliver 函数
将在缓存中找到请求的内容发送给客户端前调用此方法
此函数一般以如下几个关键字结束
error code [reason]
deliver
restart 重新启动流程,增加启动次数,如果重新启动次数高于max_restarts 发出一个错误警告
8 vcl_error
出现错误时调用此函数。
此函数一般以如下几个关键字结束
deliver。
restart
在vcl 中有个三个重要的数据结构:request,response,object
request: 数据从客户端进来,对应req对象,当varnish 收到一个请求的时候就会创建req对象,在vcl_recv中的大部分工作都是在req对象展开的
response:数据从后端服务器过来,对应beresp 对象,它包含从后端服务器传递过来数据的头信息,在vcl_fetch 中的大部分工作都是在beresp 对象展开的。
object:存储在cache 中的数据,对于obj对象,大多数只读的对象存贮在内粗中,只有obj.ttl是可写的,其余都是只读的
vcl 支持下列运算符
= 赋值
== 比较
~ 匹配
! 否定
&&逻辑与
|| 逻辑或
三 varnish 请求处理流程
详细的处理过程
四 varnish 内置公用变量
1 VCL 内置的公用变量可以用在不同的VCL 函数中,根据这些公用变量使用不同阶段,下面依次介绍当请求到达后,可以使用的公用变量如下所示
req.backend 指定对应的后端主机
server.ip 表示服务器端IP
client.ip 表示客户端IP
req.request 指定请求类型,例如GET,HEAD,POST等
req.url 指定请求的地址
req.proto 表示客户端发起请求的HTTP协议版本
req.http.header 表示请求中http头部信息
req.restarts 表示请求重启的次数,默认最大值为4
req.grace 表示,当一个请求命中了一个刚刚过期的object,由于回源需要一段时间,为了立刻返回,那么在过期后的req.grace时间内,可以将过期的那个object返回给客户端,当然,这要求beresp.grace >= req.grace
2 varnish在向后端主机请求时,可以使用的公用变量如下所示:
beresp.request 指定请求的类型,例如GET,HEAD等
beresp.url 指定请求的地址
beresp.proto 表示客户端发起请求的http 协议版本
beresp.http.header 表示对应请求中http 头部信息
beresp.ttl 表示缓存的生存周期,也就是cache保留多长时间,单位是秒
beresp.grace 表示一个object即使已经过期了,仍然在缓存中存放一段时间
beresp.saintmode 设置saint模式,Saint mode允许您抛弃一个后端服务器或者另一个尝试的后端服务器或者cache中服务陈旧的内容
beresp.do_gzip 在存储object之前gzip对象,默认是false
3 从cache 或者后端主机获取内容后,可以使用的公用变量如下所示
obj.status 表示返回内容的请求状态代码,例如200,302,504等
obj.cacheable 表示返回的内容是否可以缓存,也就是说,如果HTTP返回时200.203,300,301,302,404,410等,并且有非0的生存期,则可以缓存
obj.valid 表示是否是有效的HTTP应答
obj.reqponse 表示返回内容的请求状态信息
obj.proto 表示返回内容的HTTP协议版本
obj.ttl 表示返回内容的生存周期,也就是缓存时间,单位是秒
obj.lastuse 表示返回上一次请求到现在的时间间隔,单位是妙
4 对客户端应答时,可以使用的公用变量如下所示
resp.status 表示返回给客户端的HTTP状态代码
resp.proto 表示返回给客户端的HTTP协议版本
resp.http.header 表示返回给客户端的HTTP协议版本
resp.response 表示返回给客户端的HTTP 状态信息
req.backend.healthy 后端是否健康存活,需要设置probe
五 varnish 管理工具详解
1 varnishd 指令
-a address:port 表示varnish对httpd 的监听地址及端口
-b address:port 表示后端服务器地址及端口
-d 表示使用debug 调试模式
-f file 指定varnish服务器的配置文件
-p param=value 指定服务器的参数,用来优化varnish性能
-P file varnish进程PID文件存放路径
-n dir 指定varnish的工作目录
-s kind[,storageoptions]指定varnish缓存内容的存放方式,常用的方式有:“-s file,<dir_or_file>,<size>”
其中”<dir_or_file>”指定缓存文件的存放路径,“<size>” 指定缓存文件的大小
-t 指定缺省的TTL 值
-T address:port 设定varnish的telnet 管理端口地址及其端口
-w int[,int[,int]] 设定varnish的工作线程数,常用的方式有:
-w min,max
-w min,max,timeout
-V 显示版本号
-u 指定运行的用户
2 varnsihncsa 以NCSA 的格式显示日志
varnishncsa 工具读取共享内存的日志,然后以apache/NCSA的格式显示出来,下面的选项可以用
-a 当把日志写到文件里时,使用附加,而不是覆盖
-b 只显示varnishd和后端服务器的日志
-C 匹配正则表达式的时候,忽略大小写差异
-c 只显示varnishd和客户端的日志
-D 以进程方式运行
-d 在启动过程中处理旧的日志,一般情况下,varnishhist只会在进程写日志后启动
-f 在日志输出中使用X-Forwarded-ForHTTP 头代替client.ip
-l regex 匹配正则表达式的日志,如果没有使用-i或者-I,那么所有的日志都会匹配
-I tag 匹配指定的tag,如果没有使用-I 或者-I,那么所有的日志都会被匹配
-n 指定varnish实例的名字,用来获取日志,如果没有指定,默认使用主机名
-P file 记录PID号的文件
-r file 从一个文件读取日志,而不是从共享内存读取
-w file 把日志写到一个文件里面代替现实他们,如果不是使用-a参数就会发生覆盖,如果varnishlog在写日志时,接收到一个SIGHUP信号,他会创建一个新的文件,老的文件可以移走
-X regex 排除匹配正则表达式的日志
-x tag 排除匹配tag的日志
3 varnishlog 工具读取和显示共享内存的日志
-a 当把日志写到文件里时,使用附加,而不是覆盖。
-b 只显示varnishd和后端服务器的日志
-C 匹配正则表达式的时候,忽略大小写差异
-c 只显示varnishd和客户端的日志
-D 以进程的方式运行
-d 在启动过程中除了旧的日志,一般情况下,varnishhist只会在进程写入日志后启动
-I regex 匹配正则表达式的日志,如果没有使用-i或者-I,那么所有的日志都会匹配。
-I tag 匹配指定的tag,如果没有使用-i或者-I,那么所有的日志都会被匹配。
-k num 只显示开始的num个日志记录
-n 指定varnish实例的名字,用来获取日志,如果没有指定,默认使用主机名
-O 以请求ID 给日志分组,这个功能没有多大用处。如果要写到一个文件里面使用-w 选项
-P file记录PID号的文件
-r file 从一个文件读取日志,而不是从共享内存读取
-s sum跳过开始的num条日志
-u 无缓冲的输出
-V 显示版本,然后退出
-w file 把日志写到一个文件里代替显示他们,如果不是用-a参数就会发生覆盖,如果varnishlog在写日志时,接收到一个SIGHUP信号,他会创建一个新的文件。老的文件可以移走。
-X regex 排除匹配正则表达式的日志
-x tag 排除匹配tag 的日志
如果-o 选项被指定,需要使用正则表达式和tag来制定需要的日志
4 varnishreplay
varnishreplay 工具类似varnish logs 尝试将流量复制。下面的参数是可用的:
-a backend 发送到这台服务器的TCP 流量,指定一个地址和端口,这个选项只能被IPV4上支持
-D 打开debug模式
-r file 使用文件里的语法分析日志,这个参数是强制的
5 varnishsizes
varnishsizes 工具读取varnishd(1)的共享内存日志,生成一个连续不断更新的柱状图显示最后N 个请求的分布。N 的值取决于左上角垂直刻度的高度。水平尺度私对数。如果命中,则是使用”|”表示,如果没有命中,使用“#”表示
可使用的参数
-b 分析指定后端服务器的日志,如果没有使用-b和-c参数,varnish就充当他们
-C 忽略正则表达式的大小写
-c 分析指定客户端的日志
-d 在启动过程中处理旧的日志,一般情况下,varnishhist只会在进程写入日志后启动
-I regex 匹配正则表达式的日志,如果没有使用-I或者-I,那么所有的日子都会匹配
-I tag 匹配指定tag,如果没有使用-i或者-I,那么所有的日志都会被匹配。
-n 指定varnish实例的名字,用来获取日志,如果没有指定,默认使用主机名
-r file 读入日志文件,代替共享内存。
-V 显示版本号,然后退出。
-w delay 等待更新的延迟时间,默认是1秒
-X regex 排除匹配表达式的日志
-x tag 排斥匹配tag 的日志
6 varnishstat 工具显示一个运行varnishd实例的相关统计数据。
可用的参数
-1 只显示一次就退出
-f 使用逗号分隔字段列表来显示,使用“^”开始排除列表
-l 监听有效的列使用-f 参数
-n 指定varnishd实例来对去日志,如果没有指定,则默认使用主机名
-V 显示版本号,然后退出
-W dealy 刷新时间间隔,默认1s
中心显示中每列的含义,从左到右:
1 值
2 从最后一秒更新以来的每秒的一个平均值,或者一个不能计算的周期
3 从进程开始到现在每秒的平均值,或者是一个不能计算的周期
4 描述
当使用-1选项,输入列的含义,从左到右:
1 特征名字
2 值
3 从进程开始到现在没秒的平均值,或者是一个不能计算的周期。
4 描述
7 varnishtop 工具读取varnishd(1) 共享内存的日志,连续不断的更新和显示日志记录。使用-I,-i,-X和-x 选项适当的过滤,它可以显示一个排序关于请求的内容,客户端,用户代理,或者其他记录在日志的信息。
可选用的参数
-1 代替连续不断的更新和显示,只显示一次然后退出。。暗示:-d
-b 包含指定后端服务器的日志,如果没有使用-b或-c,那么varnishtop但当这两种角色。
-C 使用正则表达式的时候忽略大小写
-c 包含指定客户端的日志,如果没有使用-b或-c,varnishtop但当这两种角色
-d 启动的时候是使用旧的日志记录,一般那情况下,varnishtop只读取其他启动以后生产的日志。
-f 只显示日志的第一列
-I regex 匹配正则表达式的日志,如果没有使用-I 或者-i,那么所有的日志都会匹配。
-I tag 匹配指定的tag,如果没有使用-i或者-I,那么所有的日志都会被匹配。
-n 指定varnish实例的名字,用来获取日志,如果没有指定,默认使用主机名
-r file 读入日志文件,代替共享内存
-V 显示版本号,然后退出
-X regex 排除匹配表达式的日志
-x tag 排除匹配tag 的日志
参考http://www.cnblogs.com/derekchen/archive/2011/12/09/2282909.html