Varnish是一款高性能的缓存加速器,具有稳定,且效率更高,资源占用更少等特点。

缓存存储的格式:

key-value:

key:访问路径,URL, hash

value:web content

命中率:hit/(hit+miss)

文档命中率:从文档个数进行衡量;

字节命中率:从内容大小进行衡量;

注意:

缓存对象:生命周期;定期清理;

缓存空间耗尽:LRU(最近最少使用算法)

可缓存对象,不可缓存对象(用户私有数据)

缓存处理的步骤:

接收请求 --> 解析请求 (提取请求的URL及各种首部)--> 查询缓存 --> 新鲜度检测 --> 创建响应报文 -->发送响应 --> 记录日志

新鲜度检测机制:

1、  过期日期:

Expires;例:Expires:Thu, 04 Jun 2015 23:38:18 GMT,是在这个时间以前都有效

Cache-Control:max-age;例:Cache-Control:max-age=600,缓存有效时间为600s(秒)

2、有效性再验证:revalidate,就是查到缓存以后,去向服务器端发送一个条件式请求,

如果原始内容未改变,则仅响应首部(不附带body部分),响应码304 (Not Modified)

如果原始内容发生改变,则正常响应,响应码200;

如果原始内容消失,则响应404,此时缓存中的cacheobject也应该被删除;

3、条件式请求首部:

If-Modified-Since:基于请求内容的时间戳做验正;就是自从什么时间开始发生改变

If-Unmodified-Since:自从什么时间开始没有发生改变

If-Match:是否匹配

If-None-Match:是否你匹配

Etag:fdsfad9345,扩展标签,是校验码

浏览器发送一个请求,先经过缓存,如果缓存服务器没有,就会×××器端来响应,如果这个报文可以缓存,会缓存到缓存服务器,然后响应给浏览器;如果浏览器在发送一个相同的请求,如果缓存没有过期,就会从缓存服务器直接响应的

常见的缓存服务开源解决方案:

varnish, squid

要想操作varnish,需要使用varnish的操作语言vcl,vcl的配置文件首先要被c编译器编译成二进制格式,然后才被varnish加载使用

vcl: Varnish Configuration Language,缓存策略配置接口;基于“域”的简单编程语言

varnish分为管理进程和子进程

管理进程:编译VCL并应用新配置;监控vanish;初始化varnish;CLI接口;

子进程(Child/cache)包括:

Acceptor:接收新的连接请求;

workerthreads:处理用户请求;

Expiry:清理缓存中的过期对象;

Log/stats:日志相关的

日志:Shared Memory Log,共享内存日志大小默认一般为90MB,分为两部分,前一部分为计数器,后一部分请求相关的数据;

varnish如何存储缓存对象:

file:单个文件;不支持持久机制;

malloc:内存;

persistent:基于文件的持久存储;在生产中是不可用的

varnish的安装包在epel源中有提供,提供的是4.0版本的varnish,可以直接安装,

varnish的配置文件为/etc/varnish/default.vcl,

varnish的命令行参数的配置文件/etc/varnish/varnish.params

varnish的服务文件在/usr/lib/systemd/system/varnish.service

配置varnish的三种配置应用方式:

1、varnishd应用程序的命令行参数;(定义varnish主程序的工作特性)

监听的socket, 使用的存储类型等等;额外的配置参数;

-pparam=value :设置额外的参数

-rparam,param,... : 设定只读参数列表;

-fconfig:指定配置文件的,指到哪去读vcl配置文件的

-aaddress[:port][,......]:指定服务监听的地址和端口的,可以指定多个,默认监听的端口是6081(提供服务的端口)和6082(管理接口)

-s[name=]type[,options]:指定缓存使用哪一种存储机制的

-Taddress[:port]:指定管理的地址和接口

/etc/varnish/varnish.params:命令行参数的配置文件(CentOS7中常用)

2、-p选项指明的参数:(定义varnish各子进程或线程的工作特性)

运行时参数:也可在程序运行中,通过其CLI进行配置;

3、vcl:配置缓存系统的缓存机制;(指明线程中的缓存功能的工作机制)

通过vcl配置文件进行配置;

先编译,后应用;依赖于c编译器;

下面以实例和和概念相结合的方式,讲述下varnish的相关知识和简单应用

172.16.249.195为varnish所在的主机,

/etc/varnish/varnish.params文件中定义了varnish主程序的特性,即varnish启动时的参数

VARNISH_VCL_CONF=/etc/varnish/default.vcl :定义了从哪读取vcl的配置

VARNISH_LISTEN_PORT=6081:服务监听的端口,没指明地址代表所有地址

VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1:定义了管理的地址

VARNISH_ADMIN_LISTEN_PORT=6082 :定义了管理的接口

VARNISH_STORAGE="file,/var/lib/varnish/varnish_storage.bin,1G":缓存的存储机制的定义

VARNISH_TTL=120:varnish联系后端服务器的超时时间

... ...

修改缓存使用的机制,改为使用内存:VARNISH_STORAGE="malloc,128M"

提供一台主机启动httpd服务(172.16.249.115),提供测试页

for i in{1..10};do echo "Page $i on Web1" > /var/www/html/test$i.html;done

/etc/varnish/default.vcl文件中的是vcl的配置,

修改配置:

这一段是配置后端服务器地址和端口的

这样就可以启动varnish了(systemctl  start  varnish.service)

可以看到启动成功了,访问测试一下,记得端口是6081,

varnish的命令行工具:

1、varnishadm

使用varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082,进入varnish的管理接口

-S:指明密钥文件所在位置,-T:指明端口和IP地址

进入后,使用help可以查看可以使用的命令

ping:探测后端服务器是否在线

status:显示子进程的工作状态

vcl.list:显示所有可以使用的vcl文件,

vcl.load <configname><filename>:编译vcl文件(filename),然后取一个名(configname)

active:指正在使用的vcl配置文件

available:可用的vcl配置文件

vcl.use <configname>:切换使用的vcl文件

可以看到现在使用的就是test这个vcl文件了

vcl.discard <configname>:删除可用的vcl文件的

param.show [-l] [<param>] :显示参数,

param.show:显示所有的参数

-l:显示详细的信息

param.show<param>:只显示一个参数的信息

param.set <param> <value>:设置参数的

storage.list:显示正在使用的缓存列表

vcl.show boot:可以显示boot文件编译以前的样子

backend.list:显示后端服务器列表的

ban <field> <operator><arg> [&& <field> <oper> <arg>]...:清理缓存中的缓存对象

ban.list:定义的ban规则的列表

这可以动态装载vcl配置文件的,后续的很多操作都是在这个接口里操作的

2、Log:

varnishlog :显示日志信息的,需要访问一下,才会出内容的

varnishncsa:这个也是显示日志信息的的,需要访问一下,才会出内容的

这两个日志信息的显示格式不同,这两个命令行接口的使用,如有需要可以去网上搜索下

3、Top:排序后的信息

varnishtop:

4、Statistics:统计信息的

varnishstat:显示缓存相关的信息

-l:显示所有可以显示的字段

这些字段中,常用的有:

MAIN.cache_hit:缓存命中的次数

MAIN.sess_conn:统计varnish已经处理过多少请求了

MAIN.sess_drop:统计varnish已经丢弃过多少请求

... ...

-f  NAME:只显示指定字段的信息

vcl:

stateengine:各引擎之间存一定程度上的相关性;前一个engine如果可以有多种下游engine,则上游engine需要用return指明要转移的下游engine;

vcl_recv

vcl_hash

vcl_hit

vcl_miss

vcl_fetch

vcl_deliver

vcl_pipe

vcl_pass

vcl_error

vcl编程语言语法:

(1)//, #, /* */ 用于注释;会被编译器忽略;

(2)sub $name: 用于定义子例程;

subvcl_recv { }

(3)不支持循环;

(4)有众多内置的变量,变量的可调用位置与state engine有密切相关性;

(5)支持终止语句,return(action);没有返回值;

(6)"域"专用;

(7)操作符:=, ==, ~, !, &&, ||

条件判断语句:

if(CONDTION) {

}else {

}

变量赋值:set  name=value

撤销变量的值:unset  name

varnish中常用的变量:

req.http.HEADER:调用request报文中http协议的指定的HEADER首部;

req.http.X-Forwarded-For

req.http.Auhtorization

req.http.cookie

req.request:请求方法

client.ip:客户端IP;

vcl(v3)的工作机制流程图:

state engine workflow(v3):vcl的v3版本的引擎工作机制:

vcl_recv--> vcl_hash --> vcl_hit --> vcl_deliver

vcl_recv--> vcl_hash --> vcl_miss --> vcl_fetch --> vcl_deliver

vcl_recv--> vcl_pass --> vcl_fetch --> vcl_deliver

vcl_recv--> vcl_pipe

vcl(v4)的工作机制流程图:

可以去这里查看https://www.varnish-software.com/book/4.0/_p_w_picpaths/simplified_fsm.svg

state engine(v4)

vcl_recv

vcl_pass

vcl_pipe

vcl_hash

vcl_hit

vcl_miss

vcl_backend_fetch

vcl_backend_response

vcl_backend_error

vcl_purge

vcl_synth

state engine workflow(v4):vcl的v34版本的引擎工作机制跟v3类似,就不再多解释了

下面演示操作vcl,实现一些简单应用:在CentOS7中演示,使用的varnish为4.0的版本

首先备份一份/etc/varnish/default.vcl,复制/etc/varnish/default.vcl到/etc/varnish/test.vcl

修改/etc/varnish/test.vcl配置文件:

在sub vcl_recv {}里面加入下面内容:

if (req.method == "PRI") {

/* We do not support SPDY or HTTP/2.0 */

return (synth(405));

}

if (req.method != "GET" &&

req.method != "HEAD" &&

req.method != "PUT" &&

req.method != "POST" &&

req.method != "TRACE" &&

req.method != "OPTIONS" &&

req.method != "DELETE") {

/* Non-RFC2616 or CONNECT which is weird. */

return (pipe);

}

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);

}

return (hash);

然后保存,使用varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082进入管理接口

然后使用vcl.load test1 test.vcl 装载刚在我们编写的配置文件,如果配置文件有错,会报错的;然后查看下vcl可用列表,使用vcl.use test1切换到test1上

这定义的是一些默认的信息,没法测试,能加载成功就没问题了

下面修改test.vcl,在sub vcl_deliver {}中加入

if (obj.hits>0) {

set resp.http.X-Cache = "HIT";

} else {

set resp.http.X-Cache = "MISS";

}

这是自己定义的一个响应报文首部,如果命中就显示HIT,没命中显示MISS;obj.hits是命中的次数

保存退出,然后在varnishadm接口下输入下面内容:

然后访问测试下:用一台虚拟机使用curl命令测试,-I选项是显示报文首部信息的

可以看到第一次请求是是没有缓存的,第二次就使用缓存了

varnish中的内置变量:

变量种类:

client

server:是varnish本身相关的

req:客户端发的请求

resp:缓存服务器或代理服务器响应的

bereq:是varnish往后端服务器请求的

beresp:后端服务器响应过来的内容

obj:后段服务器响应过来的内容或者从缓存中取得的内容的属性

storage:缓存存储有效性的

bereq

bereq.http.HEADERS:由varnish发往backend server的请求报文的指定首部;

bereq.request:请求方法;

bereq.url:请求的url

bereq.proto:使用的协议版本

bereq.backend:指明要调用的后端主机;

beresp

beresp.proto:使用的协议版本

beresp.status:后端服务器的响应的状态码

beresp.reason:原因短语;

beresp.backend.ip:后端服务器的ip地址

beresp.backend.name:后端服务器的主机名称

beresp.http.HEADER:从backend server响应的报文的首部;

beresp.ttl:后端服务器响应的内容的余下的生存时长;

obj

obj.ttl:对象的ttl值;

obj.hits:此对象从缓存中命中的次数;

server

server.ip:缓存服务器自己的ip地址

server.hostname:缓存服务器自己的主机名

req

rep.http

rep.url

......

resp

resp.http

resp.status

... ...

storage

storage.<name>.free_space:缓存空间的空闲空间大小

storage.<name>.use_space:缓存空间的已用空间大小

storage.<name>.happy:缓存是否还有效

Functions(函数)

ban(expression):清理缓存的

return()

new()

regsub(str,regex,sub):正则表达式替换,把str替换为sub,但只替换第一次出现的

regsuball(str,regex,sub):正则表达式替换,把str替换为sub,替换所有的

详细的varnish的内置变量等可以查看官方文档:

https://www.varnish-cache.org/docs/4.0/reference/vcl.html#varnish-configuration-language

在刚才的test.vcl配置文件中修改,在sub vcl_deliver{}中修改如下:

然后在加载,使用

测试下

可以看到使用成功了

示例:强制对某资源的请求,不检查缓存

修改test.vcl如下,在sub vcl_recv {}里加入:

if (req.url ~ "^/test7.html$") {

return(pass);

}

然后在varnishadm命令行接口中做,vcl.load和vcl.use

然后做测试,首先请求其他资源,可以看到能使用缓存

然后请求test7.html

可以看到没有使用缓存

强制对下面两类资源的请求,不检查缓存;

/admin

/login

修改test.vcl配置文件,修改配置文件的sub vcl_recv {},修改为如下:

if(req.url ~ "(?i)^/login" || req.url ~ "(?i)^/admin") {

return(pass);

}

然后在后端的服务器的/var/www/html目录下,创建每一个admin目录,然后提供测试页,然后在varnishadm命令行接口中做,vcl.load和vcl.use,在测试可以看到不缓存。这里就不再演示了,跟上面的类似。

示例:对特定类型的资源取消其私有的cookie标识,并强行设定其可以varnish缓存的时长

修改test.vcl配置文件,在vcl_backend_response{}中,加入下面这些内容:

if (beresp.http.cache-control !~ "s-maxage") {

if(bereq.url ~ "(?i)\.jpg$") {

setberesp.ttl = 3600s;

unsetberesp.http.Set-Cookie;

}

if(bereq.url ~ "(?i)\.css$") {

setberesp.ttl = 600s;

unsetberesp.http.Set-Cookie;

}

}

然后在varnishadm命令行接口中做,vcl.load和vcl.use

然后在后端主机上加载一个图片,在/var/www/html目录下,下载1.jpg和2.jpg的图片

然后在访问测试下,因为首部显示的不全,一般默认缓存一会就结束了,我们在里面定义的是定义的是3600s,这个缓存是缓存在varnish中,所以一个小时内请求这个资源都会使用缓存

等几分钟,然后在访问这个资源,会发现还是使用缓存

这样就做好了,就是不太容易看出效果,

backend server的定义:

backendname {

.attribute = "value";

}

.host:backend主机的IP;

.port:backend主机监听的PORT;

.probe:对backend做健康状态检测;

.probe = {...}

.max_connections:并连接最大数量;

后端主机的健康状态检测方式:

probename {

.attribute = "value";

}

.url:判定BE健康与否要请求的url;

.expected_response:期望响应状态码;默认为200;

示例:做两个后端服务器,然后做健康状态检测,再做下分离,让访问图片资源的调度到一台后端服务器上,访问其他资源的调度到令一台后端主机上

修改test.vcl配置文件,如下:

然后在varnishadm命令行接口中做,vcl.load和vcl.use

然后打开另一个虚拟机(172.16.249.159)设置测试页,for i in {1..10};do echo "Page $i in Web2" >/var/www/html/test$i.html ;done,这个主机里没有图片

在varnishadm命令行接口中,使用backend.list,可以查看到后端服务器的信息和状态

访问测试

可以看到图片资源的是发送给web1主机(172.16.249.115)了,请求的.html资源的是发送给web2主机(172.16.249.159)了

示例:实现负载均衡

修改test.vcl配置文件:

这样负载均衡就定义好了,但是这样不好查看效果,因为有缓存,为了演示效果加入

就是访问test7.html时不让缓存,这样访问时就可以看到负载均衡效果了

然后在varnishadm命令行接口中做,vcl.load和vcl.use

访问测试

可以看懂访问test7.html时是负载均衡,访问其他资源时,是使用的缓存,所以不会变

或者使用这个方式测试,每次使用一个新资源范围,也可以看到负载均衡效果

直接在物理机中测试也行,物理机中的浏览器访问时是不允许缓存的,所以可以看到负载均衡效果,如果你的物理机的浏览器对这些资源是允许缓存的话,就只能用上面的方法定义一个资源,让它不缓存

可以负载均衡

这样负载均衡就做好了

如果有不明白的配置可以到这个连接下去查看varnish的官方配置示例:https://www.varnish-cache.org/trac/wiki/VCLExamples

转载于:https://blog.51cto.com/10530982/1708979

Varnish的相关知识,varnish的简单应用相关推荐

  1. 项目架构相关知识的个人简单理解(水平有限,勿喷)

    (一)传统架构 一台Web应用服务器Tomcat并发量为400,如果当并发量为40000时,理论上需要100台: 同一个工程部署到多台服务器上就会存在两个问题: 问题1: 在Tomcat集群中节点数量 ...

  2. c语言串的存储操作完整,c语言中关于串的相关知识以及操作

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 1 串的基本概念 串,即是字符串,由零个或者多个字符组成的有限序列,是数据元素为单个字符的特殊线性表.一般记为:S1=' ...

  3. 关于 Oracle ACFS 相关知识的简单学习

    作者 | JiekeXu 来源 | JiekeXu之路(ID: JiekeXu_IT) 转载请联系授权 | (微信ID:xxq1426321293) 大家好,我是 JiekeXu,很高兴又和大家见面了 ...

  4. https ssl证书的工作原理及使用相关知识收集

    https ssl证书的工作原理及使用相关知识收集 SSL 与 数字证书 的基本概念和工作原理 前言 SSL是让人头大的东西,看起来很复杂,我学过信息安全课,但是对SSL仍然是模糊一片.对于数字证书也 ...

  5. shell的相关知识(变量、脚本定义)

    一.shell的相关知识: 1.对于shell编程语言大体分为:机器语言.汇编语言.高级语言 2.shell变量类型:事先确定数据的存储格式和长度 shell变量分为:字符型.数值型 数值型又分为:整 ...

  6. 视频压缩算法的相关知识

    视频压缩算法的相关知识 MPEG-1 MPEG 视频压缩编码后包括三种元素:I帧(I-frames).P帧(P-frames)和B帧(B-frames).在MPEG编码的过程中,部分视频帧序列压缩成为 ...

  7. WinForm开发,窗体显示和窗体传值相关知识总结

    以前对WinForm窗体显示和窗体间传值了解不是很清楚 最近做了一些WinForm开发,把用到的相关知识整理如下 A.WinForm中窗体显示显示窗体可以有以下2种方法: Form.ShowDialo ...

  8. VMware虚拟网络相关知识

    VMware虚拟网络相关知识 虚拟网桥         通过虚拟网桥把虚拟机的虚拟网卡连接到宿主机的物理网卡上.通过它可以将虚拟机连接到宿主机所在的外部网络.如果宿主机上不止是一个物理网卡时,采用定制 ...

  9. mysql日志的作用_MySQL 日志相关知识总结

    数据库中用于存储数据的文件称为data file,日志文件称为log file.此外,如果每次读写都是直接访问磁盘,性能很差,所以数据库是有缓存的,数据缓存是data buffer,日志缓存log b ...

最新文章

  1. 北京交大计算机学院王浩业,双胞胎双双“吹”进北交大
  2. Nagios基本搭建
  3. python什么时候用类方法_小白提问:python 在什么时候用函数,什么时候用类?...
  4. 网格自适应_Abaqus网格重划自适应技术
  5. Tomcat中实现websocket和browser端访问
  6. Swift中的#pragma mark?
  7. [USACO12OPEN]Unlocking Block【BFS / 广搜】
  8. VINS(三)IMU预积分
  9. SC;FC;LC;光纤接口介绍
  10. (HDU-1564)Play a game(博弈论)
  11. IllegalStateException: Failed to introspect annotated methods on class org.springframework.boot.web.
  12. 【技巧】Unity 获取Android设备系统语言
  13. 主会场与分会场直播场景自由切换的实际应用效果
  14. 计算机电缆线对成缆系数,电线电缆的成缆系数是什么含义?
  15. 谈谈AssetStore及其脱离Unity下载方法
  16. 大数据工程师(开发)面试系列(7)
  17. Linux(redhat)镜像
  18. Chp1-1 数据结构的基本概念
  19. 基于SpringBoot+MyBatis实现的私人影院系统
  20. Innosetup打包脚本常用设置大全

热门文章

  1. 【uoj#174】新年的破栈 贪心
  2. Python 进阶 之 enumerate()函数
  3. cdh-5.10.0搭建安装
  4. 网络流 小结(更新时间2015/8/8)更新中
  5. 显示器接口VGA、DVI、HDMI、DP
  6. python通过代理自动发邮件脚本_python自动发送邮件脚本
  7. mysql now的时间问题
  8. 浅谈HTTP中Get与Post的区别_转
  9. winform B窗體調用A窗體的DATAGRIDVIEW刷新
  10. java中length,length(),size()区别