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访问时,会显示不允许执行此操作
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/L835311324/article/details/82764513
今日推荐