Varnish 简介
Varnish 是一款高性能且开源的反向代理服务器和 HTTP 加速器,其采用全新的软件体系机构,和现在的硬件体系紧密配合,与传统的 squid 相比,varnish 具有性能更高、速度更快、管理更加方便等诸多优点,很多大型的网站都开始尝试使用 varnish 来替换 squid,这些都促进 varnish 迅速发展起来。
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)状态。将获取到的数据发给客户端,然后完成本次请求。
看完文字后再看图:
varnish 配置文件
/etc/varnish/varnish.params: 配置varnish服务进程的工作特性,例如监听的地址和端口,缓存机制;
cat /etc/varnish/varnish.params
# Set this to 1 to make systemd reload try to switch VCL without restart.
RELOAD_VCL=1
# Main configuration file. You probably want to change it.
VARNISH_VCL_CONF=/etc/varnish/default.vcl
# Default address and port to bind to. Blank address means all IPv4
# and IPv6 interfaces, otherwise specify a host name, an IPv4 dotted
# quad, or an IPv6 address in brackets.
# VARNISH_LISTEN_ADDRESS=192.168.1.5
VARNISH_LISTEN_PORT=80 #varnish 监听端口
# Admin interface listen address and port
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
VARNISH_ADMIN_LISTEN_PORT=6082
# Shared secret file for admin interface
VARNISH_SECRET_FILE=/etc/varnish/secret
# Backend storage specification, see Storage Types in the varnishd(5)
# man page for details.
VARNISH_STORAGE="malloc,256M" #调节该选项可以调整varnish 缓存大小
Varnish VCL
VCL有多个状态引擎,状态之间存在相关性,但状态引擎彼此间互相隔离;每个状态引擎可使用return(x)指明关联至哪个下一级引擎;每个状态引擎对应于vcl文件中的一个配置段,即为subroutine;varnish 内键的 vcl 参数在 /usr/share/doc/varnish-4.0.4/builtin.vcl ,默认的vcl 配置在 /etc/varnish/default.vcl 里面。通常我们建议修改default.vcl 文件来修改vcl 配置。
VCL 语法比较简单,跟 C 和 Perl 比较相似。主要有以下几点:
1. 块是由花括号分隔,语句以分号结束,使用‘ # ’符号可以添加注释。
2. VCL 使用指定运算符“=”、比较运算符“==”、逻辑运算符“!,&&,!!”等形式,还支持正则表达式和用“~”进行 ACL 匹配运算。
3. VCL 没有用户自己定义的变量,你可以在 backend、request 或 object 上设置变量值,采用 set 关键字进行设置。例如 set req.backend = director_employeeui;
VCL 内建变量:
req.*:request,表示由客户端发来的请求报文相关;
req.http.*
req.http.User-Agent, req.http.Referer, …
bereq.*:由varnish发往BE主机的httpd请求相关;
bereq.http.*
beresp.*:由BE主机响应给varnish的响应报文相关;
beresp.http.*
resp.*:由varnish响应给client相关;
obj.*:存储在缓存空间中的缓存对象的属性;只读;
VCL常用变量:
bereq., req.:
bereq.http.HEADERS
bereq.request:请求方法;
bereq.url:请求的url;
bereq.proto:请求的协议版本;
bereq.backend:指明要调用的后端主机;
req.http.Cookie:客户端的请求报文中Cookie首部的值;
req.http.User-Agent ~ “chrome”
beresp., resp.:
beresp.http.HEADERS
beresp.status:响应的状态码;
reresp.proto:协议版本;
beresp.backend.name:BE主机的主机名;
beresp.ttl:BE主机响应的内容的余下的可缓存时长;
obj.*
obj.hits:此对象从缓存中命中的次数;
obj.ttl:对象的ttl值
server.*
server.ip:varnish主机的IP;
server.hostname:varnish主机的Hostname;
client.*
client.ip:发请求至varnish主机的客户端IP;
VCL 配置举例:
示例1:强制对某类资源的请求不检查缓存:
vcl_recv {
if (req.url ~ "(?i)^/(login|admin)") {
return(pass);
}
}
示例2:对于特定类型的资源,例如公开的图片等,取消其私有标识,并强行设定其可以由varnish缓存的时长; 定义在vcl_backend_response中;
sub vcl_backend_response {
if (beresp.http.cache-control !~ "s-maxage") {
#后端服务器响应给缓存服务器的响应报文中不包含s-maxage
if (bereq.url ~ "(?i)\.(jpg|jpeg|png|gif|css|js)$") {
#匹配缓存服务器请求后端web服务器的url中包括以这些点结尾的文件
unset beresp.http.set-cookie; #不设定响应cookie
set beresp.ttl = 3600s; #设定缓存时长为3600s
}
}
示例3:定义在vcl_recv中;
if (req.restarts == 0) {
if (req.http.X-Fowarded-For) {
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + "," + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
在 后台server http 配置文件定义日志格式:
LogFormat "%h %{x-forwarded-for}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" haclient #加上xforword字段
CustomLog logs/access_log haclient 应用刚定义的日志格式
tail -f /var/log/httpd/access_log 在后端日志上监控可以看到客户端地址
示例4:定义多个后台real server并实现负载均衡:
vim /etc/varnish/default.vcl
vcl 4.0;
import directors; #实现负载均衡要先导入这个模块
probe healthchk { #定义健康检查名称
.url = "/index.html";
.interval = 2s;
.timeout = 2s;
.window = 6 ;
.threshold = 5 ;
}
backend sgr1 {
.host = "192.168.10.30";
.port = "80";
.probe = healthchk; #建议对realserver 配置健康检查
}
backend sgr2 {
.host = "192.168.10.32";
.port = "80";
.probe = healthchk;
}
sub vcl_init {
new srvs=directors.round_robin(); #用轮询调度
srvs.add_backend(sgr1);
srvs.add_backend(sgr2);
}
Varnishadm
varnishadm 命令用来对varnish 配置文件加载,语法检查,配置等,默认是tcp6082端口,用法如下:
varnishadm -S /etc/varnish/secret -T [ADDRESS:]PORT
例如:varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
vcl.load test2 default.vcl #加载名称为test2的 配置,可自定义取名
vcl.use test2 激活
vcl.discard test1 —删除某个配置
backend.list —查看后端主机
vcl.list 查看配置列表
vcl.load:装载,加载并编译;
vcl.use:激活;
vcl.discard:删除;
vcl.show [-v] :查看指定的配置文件的详细信息;
param.show -l:显示列表;
param.show
param.set
缓存存储:
storage.list
后端服务器:
backend.list