首页 » Linux » CentOS » Varnish讲解及示例

Varnish讲解及示例

 

Varnish是一款高性能且开源的反向代理服务器和HTTP加速器,可以有效降低web服务器的负载,提升访问速度。

web服务器典型的处理过程,要经过一系列的步骤来处理接收到的每个请求。有可能需要启动一个进程来处理请求,有可能需要从磁盘上载入文件,或者启动内部线程来编译执行一些脚本。在执行脚本的过程中,还会进行很多别的动作,比如进行数据库查询,读取文件等等。client有很多请求是重复的,但web服务器无法记住曾经作出的响应,还会重复上面复杂的处理过程。当成百上千个请求并发访问时,服务器的负载会很快上升,出现系统资源不够的情况。

当把Varnish部署上之后,web请求的处理过程会有一些变化。client的请求将首先被Varnish接受。Varnish将分析接收的请求,并将其转发到后端的web服务器上。后端的web服务器对请求进行常规的处理,并将依次将处理结果返回给Varnish。Varnish的核心功能是能将后端web服务器返回的结果缓存起来,如果发现后续有相同的请求,Varnish不会把这个请求转发到web服务器,而是返回缓存中的结果。这将有效的降低web服务器的负载,提升响应速度,并且每秒可以响应更多的请求。Varnish速度很快的另一个主要原因是其缓存全部都是放在内存里的,这比放在磁盘上要快的多。诸如此类的优化措施使得Varnish的相应速度超乎想象。但考虑到实际的系统中内存一般是有限的,所以需要手工配置一下缓存的空间限额,同时避免缓存重复的内容。

Varnish与Squid的对比:
Squid是一个高性能的代理缓存服务器,它和varnish之间有诸多的异同点,这里分析如下:
下面是他们之间的相同点:
(1)都是一个反向代理服务器,
(2)都是开源软件,
下面是它们的不同点,也是Varnish的优点:
(1)Varnish的稳定性很高,两者在完成相同负荷的工作时,Squid服务器发生故障的几率要高于Varnish,因为使用Squid要经常重启。
(2)Varnish访问速度更快,Varnish采用了“Visual Page Cache”技术,所有缓存数据都直接从内存读取,而squid是从硬盘读取,因而Varnish在访问速度方面会更快。
(3)Varnish可以支持更多的并发连接,因为Varnish的TCP连接释放要比Squid快。因而在高并发连接情况下可以支持更多TCP连接。
(4)Varnish可以通过管理端口,使用正则表达式批量的清除部分缓存,而Squid是做不到的。
当然,与传统的Squid相比,Varnish也是有缺点的,列举如下:
(a)varnish在高并发状态下CPU、IO、内存等资源开销都高于Squid。
(b)varnish进程一旦Hang、Crash或者重启,缓存数据都会从内存中完全释放,此时所有请求都会发送到后端服务器,在高并发情况下,会给后端服务器造成很大压力。

varnish官方网站:www.varnish-cache.org

 

varnish安装与配置:

#yum install varnish

#systemctl start varnish.service 启动(默认6081端口)

配置文件:

/etc/varnish/varnish.params 配置varnish服务进程的工作特性;

/etc/varnish/default.vcl 配置各Child/Cache线程的工作属性;

主程序:/usr/sbin/varnishd

CLI interface命令行接口:/usr/bin/varnishadm

Shared Memory Log共享内存日志工具:

/usr/bin/varnishhist
/usr/bin/varnishlog
/usr/bin/varnishncsa
/usr/bin/varnishstat
/usr/bin/varnishtop

测试工具程序:/usr/bin/varnishtest

VCL配置文件重载程序:/usr/sbin/varnish_reload_vcl

Systemd Unit File:

varnish服务:/usr/lib/systemd/system/varnish.service
varnish日志:/usr/lib/systemd/system/varnishlog.service
日志持久的服务:/usr/lib/systemd/system/varnishncsa.service

/etc/varnish/varnish.params文件介绍:

RELOAD_VCL=1 自动重新装载缓存策略,1表示脚本启动自动重新装载缓存策略配置文件
VARNISH_VCL_CONF=/etc/varnish/default.vcl 默认的缓存策略配置文件
VARNISH_LISTEN_PORT=6081 默认监听端口
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1  管理员management进程管理地址
VARNISH_ADMIN_LISTEN_PORT=6082 管理员management进程管理端口
VARNISH_SECRET_FILE=/etc/varnish/secret 启动装载的密钥文件位置,域共享密钥
VARNISH_STORAGE="file,/var/lib/varnish/varnish_storage.bin,1G"  缓存类型和大小
VARNISH_STORAGE="malloc,256M" 缓存类型和大小
VARNISH_TTL=120 超时时长
VARNISH_USER=varnish 用户
VARNISH_GROUP=varnish 组

 

varnish命令行工具(类似于mysql用法)varnishadm:

varnish>help 帮助

配置文件相关:

vcl.list :显示vcl配置文件列表
vcl.load:重新编译加载vcl配置,需要指明自定义版本名称,和需要编译的文件default.vcl位置;
vcl.use:使用编译的配置文件,指明自定义版本名称,激活;
vcl.discard:手动清理版本,否则旧版本配置信息会在varnish重启后丢弃,删除;
vcl.show:显示指定的配置文件详细信息,指明自定义版本名称;

运行时参数:

param.show -l:显示列表;
param.show <PARAM>
param.set <PARAM> <VALUE>

缓存存储列表:storage.list

后端服务器列表:backend.list

其他:

varnish>status 显示运行状态

varnish>ping 是否在线

varnish>stop 停止varnish服务

varnish>start 启动varnish服务

 

显示运行的varnishd实例的统计信息:varnishstat

Name:计数器名称;
Current:计数器的当前值;
Change:最后一个更新间隔的每秒平均变化;
Average:varnish daemon运行时计数器的平均值,或者该计数器无法被平均时的周期;
Avg_10:在最后10个更新间隔的移动平均值;
Avg_100:在最后100个更新间隔的移动平均值;
Avg_1000:在最后1000个更新间隔的移动平均值;

 

VCL:VCL(varnish configuration language)是varnish配置语言,其用来定义varnish 的存取策略,vcl语法跟C和perl比较相似。

varnish状态引擎:

VCL有多个状态引擎,状态之间存在相关性,但彼此间互相隔离;每个状态引擎可使用return(x)指明关联至哪个下一级引擎;

6

vcl_recv:接收请求。

Lookup状态,进入此状态后,会在hash表中查找数据,若找到,则进入Hit(命中)状态,否则进入miss(未命中)状态。

pipe状态:请求直接传递至后端主机,在请求和返回的内容没有改变的情况下,将不变的内容返回给客户端,直到这个链接被关闭。

Pass状态:在此状态下,会进入后端请求,即进入Fetch状态。

Fetch状态:在Fetch状态下,对请求进行后端获取,发送请求,获得数据,是否进行本地存储。

Deliver状态:将获取到的数据发送给客户端,然后完成本次请求。

vcl语法格式:

(1) 支持注释符//,/*... */, #;
(2) sub $name:定义子例程;sub vcl_recv {...};
(3) 不支持循环,支持条件判断;
(4) 有大量的内建变量,生效位置有特定要求;
(5) 使用终止语句return,来决定下一个状态引擎;没有返回值;
(6) 操作符:=,==, !, ~, &&, ||,>, <, >=, <=

官方文档:https://www.varnish-cache.org/docs/4.0/users-guide/vcl-syntax.html

常用变量(摘自于网络,想了解更详细,请看官方文档https://www.varnish-cache.org/docs/4.0/reference/vcl.html#varnish-configuration-language):

F9

(1)在任何状态引擎中均可
.host后端主机的主机名或者IP
.port后端主机的服务名或者端口号
(2)用于处理请求阶段
client.ip客户端ip
server.hostname缓存服务器主机名
server.ip缓存服务器ip
server.port缓存服务器端口
req.request:请求方法
req.url:请求的URL
req.proto:请求的HTTP协议版本
req.backend:指定用于服务此次请求的后端主机
req.backend.healthy:后端主机的健康状态
req.http.HEADER:调用request报文中http协议的指定的HEADER首部
req.can_gzip:客户端是否能结束gzip压缩格式响应内容
req.restarts:此请求被重启的次数
req.grace:宽限期响应
(3)varnish向backend主机发起请求前可用的变量
bereq.request:后端主机请求方法
bereq.url:后端主机请求路径
bereq.proto:后端主机请求http协议
bereq.http.HEADER:后端主机HTTP首部
bereq.connect.timeout:等待后端建立连接的超时时长
(4)backend主机的响应报文到达本主机(varnish)后,将其放置在cache中之前可用的变量
beresp.do_stream:流式响应(接收一个响应一个)
beresp.do_gzip:是否压缩后存储
beresp.do_gunzip:是否先解压缩再存储
beresp.http.HEADER:后端主机响应http首部
beresp.proto:后端主机响应http协议
beresp.status:后端主机响应状态码
beresp.response:响应的原因短语
beresp.ttl:响应对象剩余的响应时长,单位为秒
beresp.backend.name指明此响应报文来源的后端主机的名称
beresp.backend.ip指明此响应报文来源的后端主机的ip地址
beresp.backend.port指明此响应报文来源的后端主机的端口号
beresp.storage强制varnish存储在指定的缓存后端
(5)缓存对象(从后端主机取出内容)存入cache之后可用变量
obj.proto:缓存对象响应时的协议
obj.status:缓存对象响应时的状态码
obj.response:缓存对象响应时的原因短语
obj.ttl:缓存对象响应时的生存时长
obj.hits:缓存对象响应时的命中次数
obj.http.HEADER:缓存对象响应时的的http首部
(6)在决定对请求的键做hash计算时可用变量
req.hash:指明将什么键当成hash缓存的键
(7)在为客户端准备响应报文时可用的变量
resp.proto响应的协议
resp.status响应的状态码
resp.response响应的响应原因短语
resp.http.HEADER响应的

用户自定义的变量:set unset

变量的可用位置:

wK

配置一个简单的后端示例:

当前主机IP 172.16.63.70

#vim /etc/varnish/default.vcl
backend default {
.host = "172.16.63.21";
.port = "80";
}
#vim /etc/varnish/varnish.params
VARNISH_LISTEN_PORT=80
此时需要后端的主机(172.16.63.21)已经启动一个apache服务
如果之前已经启动了varnish服务,此时reload即可(#systemctl reload varnish.service或#varnish_reload_vcl)
此时访问172.16.63.70即是后端的内容,但无法查看命中,我们在设置下:

#vim /etc/varnish/default.vcl

sub vcl_deliver {

if (obj.hits>0) {
set resp.http.X-Cache = "HIT";   设定响应报文首部
} else {
set resp.http.X-Cache = "MISS";
}
}

使配置生效,我们可以reload也可以使用以下方法:

90

测试效果:命中

E2

示例:不检查test.html缓存直接从后端来取

#vim /etc/varnish/default.vcl

sub vcl_recv {
if (req.url ~ "test.html") {
return(miss);
}
}

示例:强制对某类资源的请求不检查缓存(以login或admin开头,(?i)表示不区分大小写)

#vim /etc/varnish/default.vcl

vcl_recv {
if (req.url ~ "(?i)^/(login|admin)") {
return(pass);
}
}

原文链接:Varnish讲解及示例,转载请注明来源!

2