缓存varnish配置详解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了缓存varnish配置详解相关的知识,希望对你有一定的参考价值。

一 工作原理

在当前主流的Web服务架构体系中,Cache担任着越来越重要的作用。常见的基于浏览器的C/S架构,Web Cache更是节约服务器资源的关键。而最近几年由FreeBSD创始人之一Kamp开发的varnish更是一个不可多得的Web Cache Server。严格意义上说,Varnish是一个高性能的反向代理软件,只不过与其出色的缓存功能相比,企业更愿意使用其搭建缓存服务器。同时,由于其工作在Web Server的前端,有一部分企业已经在生产环境中使用其作为旧版本的squid的替代方案,以在相同的服务器成本下提供更好的缓存效果,Varnish更是作为CDN缓存服务器的可选服务之一。

Varnish主要有以下几点特性:

1.缓存位置:可以使用内存也可以使用磁盘。如果要使用磁盘的话推荐SSD做RAID1

2.日志存储:日志也存储在内存中。存储策略:固定大小,循环使用

3.支持虚拟内存的使用。

4.有精确的时间管理机制,即缓存的时间属性控制。

5.状态引擎架构:在不同的引擎上完成对不同的缓存和代理数据进行处理。可以通过特定的配置语言设计不同的控制语句,以决定数据在不同位置以不同方式缓存。类似于netfilter中的钩子,在特定的地方对经过的报文进行特定规则的处理。

6.缓存管理:以二叉堆格式管理缓存数据,做到数据的及时清理。




二 基本架构

1. 状态引擎

技术分享图片

2.内部处理流程

技术分享图片




三 配置详解

1. 简单安装

[[email protected]?~]#?yum?install?varnish?-y

2. 配置详解

[[email protected]?~]#?cd?/etc/varnish

配置default.vcl配置文件

[[email protected]?varnish]#?cat?default.vcl
#?使用varnish版本4的格式.
vcl?4.0;
#?加载后端轮询模块
import?directors;
#######################健康检查策略区域###########################
#?名为www_probe的健康检查策略
probe?www_probe?{
.request?=
"GET?/html/test.html?HTTP/1.1"????#?健康检查url为/html/test.html?协议为http1.1
#"Host:?www.xiaxiaodie.com"????????#?访问的域名为www.xiaxiaodie.com
"Connection:?close";????????#?检查完关闭连接
#其他参数?如?超时时间?检查间隔?等?均使用默认
}
##################################################################
#######################配置后端区域################################
backend?backend_15?{
.host?=?"172.18.67.15";
.port?=?"80";
.probe?=?www_probe;?#?使用名为www_probe的健康检查策略
}
backend?backend_16?{
.host?=?"172.18.67.16"?
.port?=?"80";
.probe?=?www_probe;?#?使用名为www_probe的健康检查策略
}
#默认后端
backend?default?{
.host?=?"172.18.67.15"?
.port?=?"80";
}
###################################################################
#?配置后端集群事件
sub?vcl_init?{
#?后端集群有4种模式?random,?round-robin,?fallback,?hash
#?random?随机
#?round-robin?轮询
#?fallback?后备
#?hash?固定后端?根据url(req.http.url)?或?用户cookie(req.http.cookie)?或?用户session(req.http.sticky)(这个还有其他要配合)
#?把backend_15?和?backend_16配置为轮询集群?取名为www_round_robin
new?www_round_robin?=?directors.round_robin();
www_round_robin.add_backend(backend_15);
www_round_robin.add_backend(backend_16);
#?把backend_15?和?backend_16配置为随机选择集群?取名为www_random
new?www_random?=?directors.random();
www_random.add_backend(backend_15,10);??#?设置backend_15后端的权重为10
www_random.add_backend(backend_16,5);???#?设置backend_16后端的权重为5
#?把backend_15?和?backend_16配置为固定后端集群?取名为www_hash?在recv调用时还需要添加东西?看recv例子
new?www_hash?=?directors.hash();
www_hash.add_backend(backend_15,1);????????#?设置backend_15后端的权重为1
www_hash.add_backend(backend_16,1);????????#?设置backend_16后端的权重为1
}
#定义允许清理缓存的IP
acl?purge?{
#?For?now,?I‘ll?only?allow?purges?coming?from?localhost
"127.0.0.1";
"localhost";
}
#?请求入口?这里一般用作路由处理?判断是否读取缓存?和?指定该请求使用哪个后端
sub?vcl_recv?{
#?域名为?www.xiaxiaodie.com?的请求?指定使用名为www_round_robin的后端集群??在集群名后加上?.backend()?如只使用单独后端?直接写后端名字即可?如?=?backend_16;
if?(req.http.host?~?"node2")?{
set?req.backend_hint?=?www_round_robin.backend();
}
#?使用固定后端集群例子?使用名为www_hash的集群
if?(req.http.host?~?"3g.xiaxiaodie.com")?{
set?req.backend_hint?=?www_hash.backend(req.http.cookie);??#?根据用户的cookie来分配固定后端?可以指定其他分配规则
}
#?其他将使用default默认后端
#?把真实客户端IP传递给后端服务器?后端服务器日志使用X-Forwarded-For来接收
if?(req.restarts?==?0)?{
if?(req.http.X-Forwarded-For)?{
set?req.http.X-Forwarded-For?=?req.http.X-Forwarded-For?+?",?"?+?client.ip;
}?else?{
set?req.http.X-Forwarded-For?=?client.ip;
}
}
#?匹配清理缓存的请求
if?(req.method?==?"PURGE")?{
#?如果发起请求的客户端IP?不是在acl?purge里面定义的?就拒绝
if?(!client.ip?~?purge)?{
return?(synth(405,?"This?IP?is?not?allowed?to?send?PURGE?requests."));
}
#?是的话就执行清理
return?(purge);
}
#?如果不是正常请求?就直接穿透没商量
if?(req.method?!=?"GET"?&&
req.method?!=?"HEAD"?&&
req.method?!=?"PUT"?&&
req.method?!=?"POST"?&&
req.method?!=?"TRACE"?&&
req.method?!=?"OPTIONS"?&&
req.method?!=?"PATCH"?&&
req.method?!=?"DELETE")?{
/*?Non-RFC2616?or?CONNECT?which?is?weird.?*/
return?(pipe);
}
#?如果不是GET和HEAD就跳到pass?再确定是缓存还是穿透
if?(req.method?!=?"GET"?&&?req.method?!=?"HEAD")?{
return?(pass);
}
#?缓存通过上面所有判断的请求?(只剩下GET和HEAD了)
return?(hash);
}
#?pass事件
sub?vcl_pass?{
#?有fetch,synth?or?restart?3种模式.?fetch模式下?全部都不会缓存
return?(fetch);
}
#?hash事件(缓存事件)
sub?vcl_hash?{
#?根据以下特征来判断请求的唯一性?并根据此特征来缓存请求的内容?特征为&关系
#?1.?请求的url
#?2.?请求的servername?如没有?就记录请求的服务器IP地址
#?3.?请求的cookie
hash_data(req.url);
if?(req.http.host)?{
hash_data(req.http.host);
}?else?{
hash_data(server.ip);
}
#?返回lookup?,?lookup不是一个事件(就是?并非指跳去sub?vcl_lookup)?他是一个操作?他会检查有没有缓存?如没有?就会创建缓存
return?(lookup);
}
#?缓存命中事件?在lookup操作后自动调用?官网文档说?如没必要?一般不需要修改
sub?vcl_hit?{
#?可以在这里添加判断事件(if)?可以返回?deliver?restart?synth?3个事件
#?deliver??表示把缓存内容直接返回给用户
#?restart??重新启动请求?不建议使用?超过重试次数会报错
#?synth????返回状态码?和原因?语法:return(synth(status?code,reason))
#?这里没有判断?所有缓存命中直接返回给用户
return?(deliver);
}
#?缓存不命中事件?在lookup操作后自动调用?官网文档说?如没必要?一般不需要修改
sub?vcl_miss?{
#?此事件中?会默认给http请求加一个?X-Varnish?的header头?提示:?nginx可以根据此header来判断是否来自varnish的请求(就不用起2个端口了)
#?要取消此header头?只需要在这里添加?unset?bereq.http.x-varnish;?即可
#?这里所有不命中的缓存都去后端拿?没有其他操作?fetch表示从后端服务器拿取请求内容
return?(fetch);
}
#?返回给用户的前一个事件?通常用于添加或删除header头
sub?vcl_deliver?{
#?例子
#?set?resp.http.*????用来添加header头?如?set?resp.http.xiaxiaodie?=?"haha";?unset为删除
#?set?resp.status?????用来设置返回状态?如?set?resp.status?=?404;
#?obj.hits????????会返回缓存命中次数?用于判断或赋值给header头
#?req.restarts????会返回该请求经历restart事件次数?用户判断或赋值给header头
#?根据判断缓存时间来设置xiaxiaodie-Cache?header头
if?(obj.hits?>?0)?{
set?resp.http.xiaxiaodie_Cache?=?"cached";
}?else?{
set?resp.http.xiaxiaodie_Cache?=?"uncached";
}
#取消显示php框架版本的header头
unset?resp.http.X-Powered-By;
#取消显示nginx版本、Via(来自varnish)等header头?为了安全
unset?resp.http.Server;
unset?resp.http.X-Drupal-Cache;
unset?resp.http.Via;
unset?resp.http.Link;
unset?resp.http.X-Varnish;
#显示请求经历restarts事件的次数
set?resp.http.xiaxiaodie_restarts_count?=?req.restarts;
#显示该资源缓存的时间?单位秒
set?resp.http.xiaxiaodie_Age?=?resp.http.Age;
#显示该资源命中的次数
set?resp.http.xiaxiaodie_hit_count?=?obj.hits;
#取消显示Age?为了不和CDN冲突
unset?resp.http.Age;
#返回给用户
return?(deliver);
}
#处理对后端返回结果的事件(设置缓存、移除cookie信息、设置header头等)?在fetch事件后自动调用
sub?vcl_backend_response?{
#后端返回如下错误状态码?则不缓存
if?(beresp.status?==?499?||?beresp.status?==?404?||?beresp.status?==?502)?{
set?beresp.uncacheable?=?true;
}
#如请求php或jsp?则不缓存
if?(bereq.url?~?"\.(php|jsp)(\?|$)")?{
set?beresp.uncacheable?=?true;
#php和jsp以外的请求
}?else?{
#如请求html?则缓存5分钟
if?(bereq.url?~?"\.html(\?|$)")?{
set?beresp.ttl?=?300s;
unset?beresp.http.Set-Cookie;
#其他缓存1小时?如css?js等
}else{
set?beresp.ttl?=?1h;
unset?beresp.http.Set-Cookie;
}
}
#开启grace模式?表示当后端全挂掉后?即使缓存资源已过期(超过缓存时间)?也会把该资源返回给用户?资源最大有效时间为6小时
set?beresp.grace?=?6h;
#返回给用户
return?(deliver);
}

配置varnish.params配置文件

[[email protected]?varnish]#?vim?varnish.params
#?Varnish?environment?configuration?description.?This?was?derived?from
#?the?old?style?sysconfig/defaults?settings
#?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
#?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"
#?User?and?group?for?the?varnishd?worker?processes
VARNISH_USER=varnish
VARNISH_GROUP=varnish
#?Other?options,?see?the?man?page?varnishd(1)
#DAEMON_OPTS="-p?thread_pool_min=5?-p?thread_pool_max=500?-p?thread_pool_timeout=300"

3.简单管理工具

[[email protected]?varnish]#?varnishadm?-S?secret?-T?127.0.0.1:6082
200????????
-----------------------------
Varnish?Cache?CLI?1.0
-----------------------------
Linux,3.10.0-327.el7.x86_64,x86_64,-smalloc,-smalloc,-hcritbit
varnish-4.0.4?revision?386f712
Type?‘help‘?for?command?list.
Type?‘quit‘?to?close?CLI?session.
help
200????????
help?[<command>]
ping?[<timestamp>]
auth?<response>
quit
banner
status
start
stop
vcl.load?<configname>?<filename>
vcl.inline?<configname>?<quoted_VCLstring>
vcl.use?<configname>
vcl.discard?<configname>
vcl.list
param.show?[-l]?[<param>]
param.set?<param>?<value>
panic.show
panic.clear
storage.list
vcl.show?[-v]?<configname>
backend.list?[<backend_expression>]
backend.set_health?<backend_expression>?<state>
ban?<field>?<operator>?<arg>?[&&?<field>?<oper>?<arg>]...
ban.list




四 访问测试

[[email protected]?varnish]#?systemctl?start?varnish.service

以上是关于缓存varnish配置详解的主要内容,如果未能解决你的问题,请参考以下文章

web缓存服务器varnish-4.1.6的部署及配置详解

Varnish缓存部署方式及原理详解

varnish页面缓存代理服务详解

高性能Web服务之varnish应用详解及实战应用

Varnish缓存代理简介与配置

varnish 4.0 缓存代理配置