Varnish(二)Varnish4.0安装与配置

安装

系统:CentOS7
Varnish版本:4.0
后端web服务器:192.168.253.158
Varnish代理服务器:192.168.253.128

192.168.253.128主机上

#wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo  #安装epel源,如果已经有了就不需要执行这个命令 (这条命令对应的是CentOS7系统)
yum install varnish -y  

Varnish是一个缓存服务器,也是个代理服务器。如果没有后端真实服务器存在提供服务,它缓存什么?所以需要先设置个后端web服务器。然后让Varnish去代理后端服务器。

192.168.253.158上设置后端web服务器

systemctl  stop firewalld 
setenforce  0
yum install nginx -y 
nginx 
echo "192.168.253.158"> /usr/share/nginx/html/index.html 

在这里插入图片描述

在这里插入图片描述

192.168.253.128上修改配置文件

[root@localhost etc]# grep -vE "#|^$" /etc/varnish/default.vcl 
vcl 4.0;
backend default {
    .host = "192.168.253.158"; ## 代理后端的WEB服务器
    .port = "80";
}
sub vcl_recv {
}
sub vcl_backend_response {
}
sub vcl_deliver {
}

启动Varnish

systemctl start varnish

进入Varnish的命令行接口

varnishadm  -S /etc/varnish/secret   # /etc/varnish/secret是认证文件

在这里插入图片描述

可以看到子进程正在运行

配置文件目录结构
[root@localhost etc]# tree   /etc/varnish/
/etc/varnish/
├── default.vcl  ##默认的Varnish配置文件
├── secret        ##认证文件
└── varnish.params ##Varnish运行参数配置
varnish.params配置文件

这个文件设置运行varnish时的参数

# 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  #默认的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=6081   #varnish监听的端口

# Admin interface listen address and port  varnish管理接口监听的地址
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"
# malloc[,size]  内存存储,[,size]用于定义空间大小;重启后所有缓存项失效;
# file[,path[,size[,granularity]]]  磁盘文件存储,黑盒;重启后所有缓存项失效;
# persistent,path,size   文件存储,黑盒;重启后所有缓存项有效;实验;

# 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"

VCL

简介

Varnish Configuration Language (VCL)是一种特定于域的语言,用于描述Varnish Cache的请求处理和文档缓存策略。加载新配置时,由Manager进程创建的VCC进程将VCL代码转换为C.此C代码通常由gcc共享对象编译。然后将共享对象加载到child进程中。

vcl状态引擎

在VCL状态引擎中,状态之间具有相关性,但彼此间互相隔离,每个引擎使用return(x)来退出当前状态并指示varnish进入下一个状态。
varnish开始处理一个请求时,首先需要分析HTTP请求本身,比如从首部获取请求方法、验正其是否为一个合法的HTT请求等。当这些基本分析结束后就需要做出第一个决策,即varnish是否从缓存中查找请求的资源。这个决定的实现则需要由VCL来完成,简单来说,要由vcl_recv方法来完成。如果管理员没有自定义vcl_recv函数,varnish将会执行默认的vcl_recv函数。然而,即便管理员自定义了vcl_recv,但如果没有为自定义的vcl_recv函数指定其终止操作(terminating),其仍将执行默认的vcl_recv函数。事实上,varnish官方强烈建议让varnish执行默认的vcl_recv以便处理自定义vcl_recv函数中的可能出现的漏洞。

常用的有几个状态引擎
vcl_recv

vcl_recv是在Varnish完成对请求报文的解码为基本数据结构后第一个要执行的子例程,它通常有四个主要用途:
(1)修改客户端数据以减少缓存对象差异性;比如删除URL中的www.等字符;
(2)基于客户端数据选用缓存策略;比如仅缓存特定的URL请求、不缓存POST请求等;
(3)为某web应用程序执行URL重写规则;
(4)挑选合适的后端Web服务器;

vcl_backend_response

vcl_backend_response在读取了后端服务器响应报文后执行

vcl_deliver

vcl_deliver,向客户端发送响应之前执行

vcl_init

在处理任何请求之前要执行的vcl代码:主要用于初始化VMODs;

vcl_fini

所有的请求都已经结束,在vcl配置被丢弃时调用;主要用于清理VMODs;

基本语法规则

  • VCL 文件以 vcl 4.0 ; 开头
  • //, # 和 /* foo */ 表示注释
  • 函数用sub关键字声明,例如 sub vcl { … } ;
  • 不支持循环,有内置变量
  • 需要用return () 进行下一个动作。例子:return(action)
  • 域专用
  • include “foo.vcl”; 包含一个VCL文件
  • import foo; 加载Varnish模块(VMOD)

VCL内置函数,关键字和操作符

函数

  • regsub(str, regex, sub) :用于基于正则表达式搜索指定的字符串并将其替换(替换一次)为指定的字符串
  • regsuball(str, regex, sub) :用于基于正则表达式搜索指定的字符串并将其替换(全部替换)为指定的字符串
  • ban(boolean expression)
  • hash_data(input):对input进行hash
  • synthetic(str)

关键词

  • call subroutine
  • return(action)
  • new
  • set
  • unset

操作符:

  • ==, !=, ~, >, >=, <, <=
  • 逻辑操作符:&&, ||, !
  • 变量赋值:=

VCL内置的公用变量

公用变量名称含义
req.backend指定对应后端主机
server.ip表示服务器IP
client.ip表示客户端IP
req.request指定请求的类型,例如GET、HEAD和POST等
req.url指定请求的地址
req.proto表示客户端发起请求的HTTP协议版本
req.http.header表示对应请求中的HTTP头部信息
req.restarts表示请求重启的次数,默认最大值为4

Varnish 在向后端主机请求时,可以使用的公用变量

公用变量名称含义
beresp.request指定请求的类型,例如GET或HEAD等
beresp.url指定请求的地址
beresp.proto表示客户端发起请求中的HTTP协议版本
beresp.http.header表示对应请求中的HTTP头部信息
beresp.ttl表示缓存的生存周期,也就是cache保留多长时间单位是秒

从cache或后端主机获取内容后,可以使用的公用变量

公用变量名称含义
obj.status表示返回内容的请求状态码,例如200、302、504等
obj.cacheable表示返回的内容是否可以缓存,也就是说,如果HTTP返回的是200、203、300、301、302、404或410等,并且有非0的生存期,则可以缓存
obj.valid表示是否是有效的HTTP应答
obj.response表示返回内容的请求状态信息
obj.proto表示返回内容的HTTP协议版本
obj.ttl表示返回内容的生存周期,也就是缓存时间,单位是秒
obj.lastuse表示返回上一次请求到现在的间隔时间,单位是秒

对客户端应答时,可以使用的公用变量

公用变量名称含义
resp.status表示返回客户端的HTTP状态代码
resp.proto表示返回客户端的HTTP协议版本
resp.http.header表示返回客户端的HTTP头部信息
resp.response表示返回客户端的HTTP状态信息

例子

举例1 :如果请求命中缓存了,则在响应报文首部X-Cache添加HIT via + 服务端ip,如果没有命中则添加MISS via + 服务端ip。因为我们添加的报文是在varnish返回客户端这个过程。所以最好在vcl_deliver这个函数里面添加。obj.hits是内建变量,用于保存某缓存项的从缓存中命中的次数;

[root@localhost etc]#  grep -Ev "#|^$" /etc/varnish/default.vcl
vcl 4.0;
backend default {
    .host = "192.168.253.158";
    .port = "80";
}
sub vcl_recv {
}
sub vcl_backend_response {
}
sub vcl_deliver {
		set resp.http.X-Cache = "HIT via " + server.ip;
    } 
    else {
		set resp.http.X-Cache = "MISS via " + server.ip;
    }
}

动态修改配置文件

varnishadm  -S /etc/varnish/secret #进入Varnish的命令行管理
#varnish的命令行管理接口内
vcl.load  X-cache /etc/varnish/default.vcl #装载 /etc/varnish/default.vcl配置文件,命名为X-cache
vcl.use X-cache #使用X-cache这个配置文件

在这里插入图片描述
可以看到X-cache这个配置文件已经激活了

可以访问一次192.168.253.128的6081端口
在这里插入图片描述
这时候我们看到缓存没有命中。因为是第一次访问,我们再次刷新就可以看到命中了
在这里插入图片描述

举例2:强制对某类资源的请求不检查缓存

vcl_recv {
		if (req.url ~ "(?i)^/(login|admin)") {  #(?i)不区分大小写
				return(pass);
		}
}

举例3:对于特定类型的资源,例如公开的图片等,取消其私有标识,并强行设定其可以由varnish缓存的时长; 定义在vcl_backend_response中;

if (beresp.http.cache-control !~ "s-maxage") {
	if (bereq.url ~ "(?i)\.(jpg|jpeg|png|gif|css|js)$") {
		unset beresp.http.Set-Cookie;
		set beresp.ttl = 3600s;
	}
}

举例4:定义在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;
	}
}		

修建缓存对象

清理缓存有2种方法purge和ban

purge

purge用于清理缓存中的某特定对象,因此,在有着明确要修剪的缓存对象时可以使用此种方式。

vcl示例

vcl 4.0;
backend default {
    .host = "192.168.253.158";
    .port = "80";
}

acl purgers {  ##设置访问控制列表
    "127.0.0.0"/8;
    "192.168.253.0"/24;
       
}

sub vcl_purge {
	return (synth(200,"Purged")); #合成一个200响应码显示已经删除了。
}

sub vcl_recv {
    if (req.method == "PURGE") {
        if (!client.ip ~ purgers) {   ##如果客户端不再访问控制列表里面 则返回405错误
  	    return(synth(405,"Purging not allowed for " + client.ip));
	}
	return(purge);
    }
}
sub vcl_backend_response {
}
sub vcl_deliver {
    if (obj.hits>0) {   
		set resp.http.X-Cache = "HIT via " + server.ip;
    } 
    else {
		set resp.http.X-Cache = "MISS via " + server.ip;
    }
}

重新装载配置文件

[root@localhost ~]# varnishadm  -S /etc/varnish/secret  
200        
-----------------------------
Varnish Cache CLI 1.0
-----------------------------
Linux,3.10.0-693.el7.x86_64,x86_64,-smalloc,-smalloc,-hcritbit
varnish-4.0.5 revision 07eff4c29

Type 'help' for command list.
Type 'quit' to close CLI session.

vcl.load PURGE_ACL /etc/varnish/default.vcl ##装载配置文件 
200        
VCL compiled.
vcl.use PURGE_ACL   ## 使用配置文件
200        
VCL 'PURGE_ACL' now active

可以看到一开始是命中缓存的,当使用PURGE请求的时候就吧缓存删除了,于是下一次访问时候,显示MISS。说明通过PURGE方法我们删除了缓存对象
在这里插入图片描述

ban

ban()是一种从已缓存对象中过滤(filter)出某此特定的对象并将其移除的缓存内容刷新机制,不过,它并不阻止新的内容进入缓存或响应于请求。在Varnish中,ban的实现是指将一个ban添加至ban列表(ban-list)中,这可以通过命令行接口或VCL实现,它们的使用语法是相同的。ban本身就是一个或多个VCL风格的语句,它会在Varnish从缓存哈希(cache hash)中查找某缓存对象时对搜寻的对象进行比较测试。

定义好的所有ban语句会生成一个ban列表(ban-list),新添加的ban语句会被放置在列表的首部。缓存中的所有对象在响应给客户端之前都会被ban列表检查至少一次,检查完成后将会为每个缓存创建一个指向与其匹配的ban语句的指针。Varnish在从缓存中获取对象时,总是会检查此缓存对象的指针是否指向了ban列表的首部。如果没有指向ban列表的首部,其将对使用所有的新添加的ban语句对此缓存对象进行测试,如果没有任何ban语句能够匹配,则更新ban列表。

对ban这种实现方式持反对意见有有之,持赞成意见者亦有之。反对意见主要有两种,一是ban不会释放内存,缓存对象仅在有客户端访问时被测试一次;二是如果缓存对象曾经被访问到,但却很少被再次访问时ban列表将会变得非常大。赞成的意见则主要集中在ban可以让Varnish在恒定的时间内完成向ban列表添加ban的操作,例如在有着数百万个缓存对象的场景中,添加一个ban也只需要在恒定的时间内即可完成。

使用方法有2种
(1)在命令行接口使用
格式:

ban <field> <operator> <arg>

示例
在这里插入图片描述
现在缓存是命中的。

[root@localhost varnish]# varnishadm  -S /etc/varnish/secret 
200        
-----------------------------
Varnish Cache CLI 1.0
-----------------------------
Linux,3.10.0-693.el7.x86_64,x86_64,-smalloc,-smalloc,-hcritbit
varnish-4.0.5 revision 07eff4c29

Type 'help' for command list.
Type 'quit' to close CLI session.

ban req.url  ~ /.*html   ##ban掉匹配到/.*html的url
200        

然后我们再次访问
在这里插入图片描述

(2)在配置文件中定义,使用ban()函数;

[root@localhost ~]# grep -Ev "#|^$"  /etc/varnish/default.vcl
vcl 4.0;
backend default {
    .host = "192.168.253.158";
    .port = "80";
}
acl purgers {
    "127.0.0.0"/8;
       
}
sub vcl_recv {
    if (req.method == "BAN") {
  	    return(synth(405,"Purging not allowed for " + client.ip));
	}
        else{
            ban("req.http.host == " + req.http.host + " && req.url == " + req.url);
	    return(synth(200,"Ban added"));
        }
    }
}
sub vcl_backend_response {
}
sub vcl_deliver {
    if (obj.hits>0) {   
		set resp.http.X-Cache = "HIT via " + server.ip;
    } 
    else {
		set resp.http.X-Cache = "MISS via " + server.ip;
    }
}

测试之前我们访问了一次显示缓存命中了,然后使用BAN请求。显示BAN 添加成功
在这里插入图片描述

然后我们再访问一次,显示缓存没有命中“MISS”
在这里插入图片描述

我们这个配置文件的访问控制列表仅允许127.0.0.1执行ban操作。当我们使用192.168.253.128这个ip访问时,会显示不允许执行此操作
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值