2019/06/06 M 企业级缓存加速-varnish缓存策略及功能讲解

在这里插入图片描述
varnish的大体架构,有守护进程varnishd组成
而大体上,varnish可以分为两类进程,
1.管理进程 manager process
2.缓存进程 cacher pricess 有很多线程来提供服务,
比如管理存储的storage 线程
管理日志和统计数据的log/stats
真正去处理运行的 worker threads

对于varnish而言,加载的配置分为两大类
1配置整个进程自己的工作特性
2配置缓存工作策略(VCL配置) 被vcc process(用vcl配置转成C语言代码,用c-compiler转换成共享对象而后供各cacher process所加载使用,
varnishi守护进程运行当中,日志和统计数据会放在共享日志区域(shared memory log),想要查看日志就需要专门的日志查看工具 varnishlog varnishstat
vagent2是用来实现支持vac的varnish访问控制台,客户端工具是varnishadm **
对于varnish来讲,所谓的缓存策略,是靠vcl来实现,vcl说白了就是能够在一个请求到达以后,来去处理位置上去精选一些位置对请求做出相关处理的一些钩子(类似iptables)状态引擎
在这里插入图片描述
fetch在4.0以后被单独独立出来,新增了几个引擎
先看3。0中的workflow工作流

在这里插入图片描述
在这里插入图片描述
一个请求到达时无非有三种情形,
1.不可查缓存 (直接交给vcl pass,然后交给VCL_fetch,取内容之后要不要缓存,依然可以定义,经过deliver,取到数据
2.允许缓存 (是否可以命中缓存,命中就直接投递,没命中到服务器取,取完之后才投递)
3.识别不了请求 (直接到后端服务器,去response
4.0以后与服务端打交道的引擎又新增了两个

在这里插入图片描述
**
vcl_backend_error 响应失败该如何
vcl_backend_response 判断如何缓存,

在这里插入图片描述
配置语句
在这里插入图片描述
这些都是vcl语言,对此类配置来讲,可以对他们,做一个总结
无非几个要点

在这里插入图片描述
4.0的配置文件必须又一个固定的行来指明整个vcl兼容性的
在这里插入图片描述
所以3到4的配置跨度非常大,区别也很大
在这里插入图片描述
1.4.0的配置文件必须又一个固定的行来指明整个vcl兼容性的
2.//单行注释,#单行注释,/
/多上注释,表明无效配置
3.所有的子进程关于状态引擎相关的配置,叫做subroutines,必须经由sub关键字来进行申明
4.对vcl而言,不支持循环,noloops,只支持状态引擎相关的内建变量
5.每个状态引擎都必须使用return来结束,以决定下一次该跳到哪个引擎上,
6.所有配置只应用一个域
在这里插入图片描述
整个vcl引擎是一个有限状态机
1.每一个请求会单独处理
2.每一个请求在任何时刻都与其他请求都是彼此隔离的,互相不干扰
3.状态是有关联的,但是彼此是隔离的
4.退出一个状态代表varnish会进入下一个状态
5.内建的vcl代码默认为一直生效,你所自定义的配置是附加在这些内建之上的

在这里插入图片描述
对vcl来讲主要有三种语法
return指明从哪个引擎跳转到哪个引擎

vcl还有一些内建的函数和变量
在这里插入图片描述
regsub 正则表达式查找替换(正则表达式默认在一行中出现两次,只替换一次,要想都替换需要用G)
regsuball(这边一行匹配到几次,就全部替换)
hash_data对数据如何做哈希运算

在这里插入图片描述
客户端的状态引擎,
后端的状态引擎有vcl_backend_fetch,到后端取,取到以后,能否进行缓存在vcl_backend_resoponse定义,
如果取不到就在vcl_backend_error合成一个错误应答,如502

在这里插入图片描述
面向客户端,收到请求后判断该往哪里去,比如vcl_pass不能查缓存的,
可以查缓存,命中了 vcl_hit,未命中vcl_miss
不是正常web服务请求 vcl_pipe
如果缓存项过期 或者需要过期,人工清理 vcl_purge
缓存修剪 vcl_synth
deliver 直接向客户端发送响应报文

在这里插入图片描述
4.0的两个特殊引擎
lnit 初始化(类似awk 的begin)在任何请求之前执行整个vcl初始化操作,比如加载一些varnish模块
finl (类似awk end),在所有请求都结束,在vcl配置被丢弃时调用,主要清理varnish模块

现在尝试去写一段代码
在这里插入图片描述
obj的变量
obj.hits 此对象从缓存中命中的次数,(可以判断整个变量是几,可以给用户发送一个相关的首部)

在这里插入图片描述
resp响应报文,http协议首部,设定整个首部叫x-cache,把这个首部的值定义为这个字段(把一个字符串拼接成另外一个字符串)
在这里插入图片描述
在这里插入图片描述
我们之前设置的返回值是不会有任何结果的
在这里插入图片描述
为了效果,修改配置
这段配置只能用在把结果要发送回客户的时候,因此要在vcl中deliver中添加

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
先连接到varnish控制台
在这里插入图片描述
用load手动加载配置+配置名+配置文件名
如果有语法错误是会报错的
这个是先定义

在这里插入图片描述
然后再是用use来使用
在这里插入图片描述
现在是没命中
在这里插入图片描述
再访问一次试试,就命中了
在这里插入图片描述
这就是自己添加一个报文首部,哪个命中哪个没命中
obj.hits是一个内建变量,用于保存某缓存项的命中的次数
操作符,~模式匹配
逻辑操作,与,或,非

在这里插入图片描述
在这里插入图片描述
req. 表示由客户端发来的请求报文相关的很多属性值
代理服务器做的事情有两边,所以要面对4种通信,
1.客户端发来的请求
2.自己发请求个后端服务器
3.后端服务器响应给代理服务器
4.自己响应给客户端的报文
能改变的只有两个,自己发送给服务器的请求。自己发给客户端的响应报文
*
在这里插入图片描述
引用客户端首部类型只要加req.http.+值
user-agent,就是保存了客户端的浏览器类型
referer,可以判断你的referer能否请求的,referer为空或者来自于自己的网站都可以请求,但是来自于别人的就不行

在这里插入图片描述
对应varnish而言模式匹配有点诡异(?!表示不匹配不区分)?是一个引导的标记位,并放在一个小括号里,来判定对于模式匹配时要不要区分大小写
在这里插入图片描述
如果期望用户的浏览器类型不能看到命令,curl的这种字符串,就可以去判定req.http.user_agent是什么,万一符合条件的话,就可以拒绝掉,让它不能查缓存也可以
在这里插入图片描述
第二类叫bereq,由代理服务器自己发给后端服务器的请求报文,可以自己加首部
bereq.http.额外set一个首部

在这里插入图片描述
berseq,后端服务器发送的响应报文,这个由后端服务器响应给varnish的响应报文
也可以引用任何首部
beresp.http.
*
在这里插入图片描述
resp是varnish自己响应给客户端的
resp.http.
*
在这里插入图片描述
在这里插入图片描述
缓存中的项的信息
在这里插入图片描述
在这里插入图片描述
请求类的包含客户端发来的请求,以及代理服务器发送的请求
这边写在一块了 be去掉就变成req了
bereq.request:请求方法 客户端 发来时 请求方法
bereq.url:请求的url
bereq.proto : 请求的协议版本
bereq.backend 指明要调用 后端主机

在这里插入图片描述
响应部分也是一样的
在这里插入图片描述
obj开头的有两个
在这里插入图片描述
在这里插入图片描述
这些变量和应用位置是有规定的,各类变量有使用位置
在这里插入图片描述
req开头的是请求相关的,基本在每个状态引擎中都可以使用(R/W表示能读能修改)
bereq开头 varnishi发送给后端服务器的,因此fetch pass,miss,pipe可以用,其他不行
beresp 后端发送的响应 报文,发送给fetch
resp,是服务器发送给客户端的,因此只能在deliver上使用
obj obj。hit就只能读,不能随便修改,因为是自己计数的
但是obj.ttl值就可以修改,缓存两小时,或者两年,响应时长都是可以修改的
域限制变量,受制于被限制的域当中的报文走到哪个阶段,跟阶段有关系

假如有些内容就不希望查缓存
在这里插入图片描述
到pass,就直接去后端服务器上去取,不会查,缓存
在这里插入图片描述
在这里插入图片描述
在后端主机上先创建一个目录
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
现在去访问,第一次访问不会命中,第二次以进HIT了
在这里插入图片描述
现在不要查询缓存如何应用
在这里插入图片描述
在这两个环节做
在这里插入图片描述
如果能匹配到就不去查询缓存
(?i)不区分大小写

在这里插入图片描述
来重新尝试编译一下
在这里插入图片描述
现在调用
在这里插入图片描述
在这里插入图片描述
现在访问主页,就可以命中缓存在这里插入图片描述
在这里插入图片描述
如果你的请求方法是PRI(http2.0专有的方法,回复405,不支持该方法)
synth是内建函数,合成一个错误响应报文

在这里插入图片描述
现在想对curl命令不做回应时
在这里插入图片描述
再来定义一次vcl
在这里插入图片描述
现在就告诉客户端405了
在这里插入图片描述
也可以改成403
在这里插入图片描述
重新装载一次
在这里插入图片描述
再去访问,就是403
在这里插入图片描述
**域链接了很多条件
如果你的请求方法不是GET,HEAD,PUT等
就非标准方法,不能清楚是否要查缓存
,就只能交给pipe了
**
在这里插入图片描述
不是get和head就返回给pass,就是只对get和head方法进行查询缓存
在这里插入图片描述
即便是你用的get和head方法也不能去查询缓存
如果请求报文中,有 authrization ,请输入用户名密码之类的
就不查询缓存

在这里插入图片描述
在这里插入图片描述
如果后端服务器发来的cache-control的值不匹配 s-maxage(maxage是控制公共缓存时长)如果没有这一项,
而且用户请求的内容是图片类型或者css类型,意思这些非私有信息,么有落实maxage
强制如果给客户端设cookie值的话,就取消
并强制这个资源set beresp.ttl为3600s,缓存一小时

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
现在可以尝试访问了

在这里插入图片描述
现在还检查不出来效果
对于特定类型的资源,公开的的图片等,可以取消私有标识,来定义缓存时间的

在这里插入图片描述
在这里插入图片描述
对于后端服务器来讲,始终希望收到真正的客户端地址(nginx是加x-forward-to)
varnishi,也有类似,如果这个请求不是被重启的(restart=0,代表新情求,而不是重启的,或者因为各种设置而重启的),加这个因为避免x-forward,改很多次
如果请求报文req.http-xfowarded-for(数值型)非0为真,0为假
如果对应的这个变量有值,自己原来的值,或者加上,隔开,用真正客户端的地址
如果没有值,就直接=客户端ip

在这里插入图片描述
这段信息应该放在req
设置后端服务器的值应该是bereq

在这里插入图片描述
如果有值就在值后面加客户端地址
在这里插入图片描述
有错误
在backend_fetch是不能使用client up

在这里插入图片描述
那就只能放在receive当中
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
为了能看出效果,来改一下日志格式
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
刷新一下
在这里插入图片描述
没有生成传不过来
在这里插入图片描述
使用curl访问一下
在这里插入图片描述
在这里插入图片描述
记录两次,说明请求被重启,所以要加个判断,不要让请求重启
在这里插入图片描述
在这里插入图片描述
再次访问
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
现在看一下默认配置有哪些
在这里插入图片描述
当请求到达hash的时候,hash中有一个默认配置,把请求的rul
做哈希计算,如果请求报文首部有host(哈希值就把主机哈希进来)
否则就哈希server.ip
return hash

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如果host是否存在,就把它的值也当做哈希中的内容
很显然就是用户请求如果主机相同,才能命中同一个键,如果不一样 ,就不能命中,出现多个ip指向一个域名的就有问题了host的值,可以让不同主机的值里面交叉命中
否则hash serverip=varnish自己的ip地址

在这里插入图片描述
缓存中的缓存项的ttl值是大于0的,直接把拿缓存响应就可以了
否则缓存就没命中(虽然键有,但是缓存没命中)
如果obj的ttl缓存时长+可以grace容忍的时间(缓存宽限的时间,就算是现在已经小于0秒但还没有超过一分钟)大于0秒
如果在宽限期内也是可以命中缓存的

在这里插入图片描述
把命中不了的缓存项命中了,把去掉的变成没去掉
把一些可缓存的,把私有信息删除

在这里插入图片描述
手动修剪缓存项,要加入指令才可以

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值