varnish实现缓存对象及反代后端主机

2018-08-04  本文已影响44人  任总

一、varnish软件

1、概述

2、工作结构
varnish结构

3、varnish的缓存存储机制( Storage Types):

[,size]用于定义空间大小;重启后所有缓存项失效;

granularity 递增大小

Massive Storage Engine,在plus版可用,意味着收费。该模式设计的容量巨大可达100TB,磁盘性能要优于file模式。

当内存空间不足以存储所有缓存数据时,应选择file 或 mse 存储。所以一般配置成file存储,当然付费的话使用mse更佳。

4、Varnish程序环境

本文主机环境为CentOS7.0,Varnish 版本 4.0

(1)、varnish的程序环境:

/etc/varnish/varnish.params: 配置varnish服务进程的工作特性,例如监听的地址和端口,缓存机制;
  /etc/varnish/default.vcl:配置各Child/Cache线程的工作属性;
主程序:
  /usr/sbin/varnishd

(2)、 varnishd 主程序的选项:
(3)、线程相关的参数:

在线程池内部,其每一个请求由一个线程来处理; 其worker线程的最大数决定了varnish的并发响应能力;

所以我们经常需要调整的参数就是thread_pool_max,thread_pool_min
计算varnish最大并发连接数=thread_pools * thread_pool_max

(4)、设置方式:

-p param=value:设定运行参数及其值; 可重复使用多次;
  -r param[,param...]: 设定指定的参数为只读状态
 
 例如: DAEMON_OPTS="-p thread_pool_min=2 -p thread_pool_max=10000 -p thread_pool_timeout=300"

5、VCL 基础

(1)、VCL概念
(2)VCL流程
image.png
(3)VCL流程解释

上图可分为两个区域:前端frontend和后端backend

前端状态可分为四个阶段:

vcl_recv #接受客户端请求,进行判断

vcl_hash  #进行hash计算,不进行判读处理,计算之后送往各个第三阶段状态引擎中

vcl_hit #缓存命中,到此处理
vcl_pass #缓存跳过
vcl_miss #缓存未命中
vcl_purge  #清理缓存
vcl_pipe #对于无法识别的http首部请求直接送入管道,交由后端处理不再处理

vcl_deliver: 大部分响应客户端的请求由此发送回去

vcl_synth:接受来自vcl_purge的任务,对于指定的缓存,进行删除处理

后端状态分为两阶段:

vcl_backend_error:后端主机错误,返回错误响应

除此之外还有两个特殊状态引擎:

vcl_init:在处理任何请求之前要执行的vcl代码:主要用于初始化VMODs;
vcl_fini:所有的请求都已经结束,在vcl配置被丢弃时调用;主要用于清理VMODs;

4、VCL语法

(1)语法特点

vcl配置文件以 vcl 4.0 开头;
C语言注释风格://, # and /* foo */ ;
子函数使用sub关键字声明, 例如sub vcl_recv { ...};
无循环, state-limited variables(受限于引擎的内建变量);
使用return(action)中断引擎状态,指向下一步处理,action为关键字 ,例如: return(pass);
可动态装载;

(2) 三类主要语法:

sub subroutine {
...
}

if CONDITION {
...
} else {
...
}

return(), hash_data()

(3) 内建函数和关键字

函数:

hash_data():指明哈希计算的数据;减少差异,以提升命中率;
regsub(str,regex,sub):把str中被regex第一次匹配到字符串替换为sub;主要用于URL Rewrite
regsuball(str,regex,sub):把str中被regex每一次匹配到字符串均替换为sub;
return():
ban(expression)
ban_url(regex):Bans所有的其URL可以被此处的regex匹配到的缓存对象;
synth(status,"STRING"):purge操作;

关键字:
  call subroutine, return(action),new,set,unset

下图为指定函数智能用于特定子函数中

image

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

正则匹配:~

(?i) 表示忽略大小写

  同时注意匹配的规则如果是字符串需要"  " 引起
(4) 变量类型:

内建变量:

第一类:req.*:request,表示由客户端发来的请求报文相关;
req.http.*
req.http.User-Agent, req.http.Referer, ...
第二类:bereq.*:由varnish发往BE主机的httpd请求相关;
bereq.http.*
第三类:beresp.*:由BE主机响应给varnish的响应报文相关;
beresp.http.*
resp.*:由varnish响应给client相关;
obj.*:存储在缓存空间中的缓存对象的属性;只读;

常用变量:

bereq.*, req.*:
bereq.http.HEADERS
bereq.request:请求方法;
bereq.url:请求的url;
bereq.proto:请求的协议版本;
bereq.backend:指明要调用的后端主机;

req.url:请求的url
req.http.Cookie:客户端的请求报文中Cookie首部的值; 
req.http.User-Agent:浏览器类型

beresp.*, resp.*:
beresp.http.HEADERS
beresp.status:响应的状态码;
reresp.proto:协议版本;
beresp.backend.name:BE主机的主机名;
beresp.ttl:BE主机响应的内容的余下的可缓存时长;

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

server.*
server.ip
server.hostname
client.*
client.ip

同时注意变量是受状态限制的,下图为可用表

image

用户自定义:
  set variable=value #定义变量
  unset variable #撤销定义的变量

二、varnish的基本安装配置和使用管理

1、varnish的基本安装

yum仓库为epel仓库
[root@varnish50 ~]# yum -y install vanish  

[root@varnish50 ~]# cd /etc/varnish
[root@varnish50 varnish]# vim varnish.params #编辑文件
# 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 #会不会自动重新编译vcl配置文件,1代表编译

# Main configuration file. You probably want to change it.
VARNISH_VCL_CONF=/etc/varnish/default.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=80#端口

# Admin interface listen address and port
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1#指定这个IP地址远程连接
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"#使用内存缓存,指定大小
VARNISH_STORAGE="file,/data/varnish/cache,1g" #使用文件格式缓存、路径、大小
# 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"传递允许

[root@varnish50 varnish]# vim default.vcl#编辑默认配置文档
# Default backend definition. Set this to point to your content server.
backend default {
    .host = "192.168.1.12";#后端服务器地址
    .port = "80";
}
[root@varnish50 varnish]# mkdir -pv /data/varnish/cache
mkdir: 已创建目录 "/data/varnish"
mkdir: 已创建目录 "/data/varnish/cache"
[root@varnish50 varnish]# chown -R varnish:varnish /data/varnish/cache/#修改属主、组
[root@varnish50 varnish]# systemctl start varnish#启动varnish
[root@varnish50 varnish]# ss -tnlp #查看端口
State       Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN      0      128             *:80                          *:*                   users:(("varnishd",pid=1728,fd=7))
root@varnish50 varnish]# varnish_reload_vcl#重载配置
测试访问后端主机

2、varnish的使用管理

1、使用格式

varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082

        help [<command>]#帮助命令
        ping [<timestamp>]#探测
        auth <response>#认证
        quit#退出
        banner#欢迎信息
        status#服务端进程状态
        start#开启服务端进程
        stop#停止服务端进程
        vcl.load <configname> <filename>#装载那个vcl
        vcl.inline <configname> <quoted_VCLstring>
        vcl.use <configname>#切换那个vcl
        vcl.discard <configname>
        vcl.list   #列出可用vcl
        param.show [-l] [<param>]查看内部线程
        param.set <param> <value>修改内部参数
        panic.show
        panic.clear
        storage.list#列出存储
        vcl.show [-v] <configname>#查看vcl配置文件内容
        backend.list [<backend_expression>]#列出后端主机
        backend.set_health <backend_expression> <state>#设置后端主机健康
        ban <field> <operator> <arg> [&& <field> <oper> <arg>]...
        ban.list    
2、vcl配置文件相关:
            vcl.list 
            vcl.load:装载,加载并编译;
            vcl.use:激活;
            vcl.discard:删除;
            vcl.show [-v] <configname>:查看指定的配置文件的详细信息;
3、运行时参数:
            param.show -l:显示列表;
            param.show <PARAM>
            param.set <PARAM> <VALUE>
            
        缓存存储:
            storage.list
            
        后端服务器:
            backend.list 

三、反代后端主机实例

1、举例:obj.hits是内建变量,用于保存某缓存项的从缓存中命中的次数;

格式:
if (obj.hits>0) {
set resp.http.X-Cache = "HIT via " + server.ip;#发送到客户端首部自定义一个叫x-cache,这个首部的值是HIT via和变量server.ip拼接而成,注意变量不加引号
} else {
set resp.http.X-Cache = "MISS via " + server.ip;
}

[root@varnish50 ~]# vim /etc/varnish/default.vcl
......
sub vcl_deliver {
   if (obj.hits>0){
       set resp.http.X-Cache = "Hit via" + server.ip;
       } else {
       set resp.http.X-Cache = "Miss form" + server.ip;
      }
 # Happens when we have all the pieces we need, and are about to send the
[root@varnish50 ~]# varnishadm  -S /etc/varnish/secret -T 127.0.0.1:6082 #进入设置模式
200        
-----------------------------
Varnish Cache CLI 1.0
-----------------------------
Linux,3.10.0-693.el7.x86_64,x86_64,-sfile,-smalloc,-hcritbit
varnish-4.0.5 revision 07eff4c29

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

vcl.load test1 default.vcl #载入默认配置
200        
VCL compiled.#编译成功

vcl.list#查询可用vcl
200        
active          0 boot
available       0 test1#可使用,未激活


vcl.use test1#使用test1
200        
VCL 'test1' now active

vcl.list#查询可用vcl
200        
available       0 boot
active          0 test1#已使用,处于活动状态

测试

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

格式:
vcl_recv {
if (req.url ~ "(?i)^/(login|admin)") {#模式匹配,要不要字符区分大小写
return(pass);

            }
        }
[root@varnish50 ~]# vim /etc/varnish/default.vcl
......
sub vcl_recv {
    if (req.url ~ "(?i)^/(login|admin)") {
 #模式匹配,不区分字符大小写
      return(pass);
                                }
                        }

 # Happens before we check if we have this in cache already.

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

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

vcl.load test2 default.vcl#编译
200        
VCL compiled.
vcl.use test2  #使用test2
200        
VCL 'test2' now active
vcl.list  #查询
200        
available       0 boot
available       0 test1
active          0 test2#处于活动状态
测试

3、匹配请求包含curl,则返回405错误

[root@varnish50 ~]# vim /etc/varnish/default.vcl
......
sub vcl_recv {
     if (req.http.User-Agent ~ "(?i)curl"){#匹配请求包含curl,则返回405错误
            return(synth(405));
        }
.....
[root@varnish50 ~]# varnishadm  -S /etc/varnish/secret -T 127.0.0.1:6082 
200        
-----------------------------
Varnish Cache CLI 1.0
-----------------------------
Linux,3.10.0-693.el7.x86_64,x86_64,-sfile,-smalloc,-hcritbit
varnish-4.0.5 revision 07eff4c29

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

vcl.load test3 default.vc#编译l
200        
VCL compiled.
vcl.use test3#使用test3
200        
VCL 'test3' now active
vcl.list#查询
200        
available       0 boot
available       0 test1
available       0 test2
active          0 test3#处于活动状态
image.png

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

格式:

 if (beresp.http.cache-control !~ "s-maxage") {#如果后端服务器首部不能匹配s-maxage字符串
            if (bereq.url ~ "(?i)\.(jpg|jpeg|png|gif|css|js)$") {#如果后端服务器匹配jpg
                unset beresp.http.Set-Cookie;#删掉cookie
                set beresp.ttl = 3600s;#设置连接时间
            }
        }

定义在vcl_recv中;

            if (req.restarts == 0) { #做等值判断,防止请求重启
                if (req.http.X-Fowarded-For) {#如果对应变量有值,则它的值加上客户端ip
                    set req.http.X-Forwarded-For = req.http.X-Forwarded-For + "," + client.ip;
                } else {
                    set req.http.X-Forwarded-For = client.ip;#如果没有值,则只加ip
                }
            }

客户端测试查看日志:

[root@rs2 ~]# vim /etc/httpd/conf/httpd.conf    #设置后端服务器日志格式    
 LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
[root@rs2 ~]# systemctl restart httpd#重启服务
[root@rs2 ~]# tail -2 /var/log/httpd/access_log
192.168.1.102 - - [31/Jul/2018:01:03:00 +0800] "GET /admin/ HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36"#能够看到客户端ip和浏览器类型等信息

5、手动清理缓存中的指定的数据,修剪数据,purge方法

[root@varnish50 ~]# vim /etc/varnish/default.vcl
.......
sub vcl_recv {
     if (req.method == "PURGE"){#当收到请求方法为purge时然后转到purge
       return(purge);
}
#     if (req.http.User-Agent ~ "(?i)curl"){#这个注释掉
#            return(synth(405));
#        }
.....
[root@varnish50 ~]# varnishadm  -S /etc/varnish/secret -T 127.0.0.1:6082 
200        
-----------------------------
Varnish Cache CLI 1.0
-----------------------------
Linux,3.10.0-693.el7.x86_64,x86_64,-sfile,-smalloc,-hcritbit
varnish-4.0.5 revision 07eff4c29

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

vcl.load test6 default.vcl #编译
200        
VCL compiled.
vcl.use test6#使用
200        
VCL 'test6' now active
vcl.list#查询
200        
available       0 boot
available       0 test1
available       0 test2
available       0 test3
available       0 test4
active          0 test6  #处于活动状态

客户端测试:

[root@vs ~]# curl -X PURGE http://192.168.1.50/index.html#使用purge方法访问网址
<!DOCTYPE html>
<html>
  <head>
    <title>200 Purged</title>   #方法
  </head>
  <body>
    <h1>Error 200 Purged</h1>
    <p>Purged</p>
    <h3>Guru Meditation:</h3>
    <p>XID: 65575</p>
    <hr>
    <p>Varnish cache server</p>
  </body>
</html>

[root@vs ~]# curl -I http://192.168.1.50/index.html#访问测试,如果能够匹配purged方法,则清理修剪缓存。
HTTP/1.1 200 OK
Date: Tue, 31 Jul 2018 09:30:43 GMT
Server: Apache/2.4.6 (CentOS) PHP/5.4.16
Last-Modified: Sun, 29 Jul 2018 16:13:53 GMT
ETag: "19-57225a18e2b77"
Content-Length: 25
Content-Type: text/html; charset=UTF-8
X-Varnish: 131076
Age: 0
Via: 1.1 varnish-v4
X-Cache: Miss form192.168.1.50#没有找到缓存
Connection: keep-alive
6、限定那些主机可以使用purge方法。
[root@varnish50 ~]# vim /etc/varnish/default.vcl
.......
vcl 4.0;
acl purgers {    #设定ip地址范围
     "127.0.0.1"/8;
      "192.168.1.0"/24;
}
.........
sub vcl_recv {
     if (req.method == "PURGE"){
     if (!client.ip ~ purgers){   #对客户端地址做匹配,如果不符合
         return (synth(405,"Purging not allowed for" + client.ip));#返回405合成一个错误响应报文
  }
       return(purge);
}
#     if (req.http.User-Agent ~ "(?i)curl"){
#            return(synth(405));
#        }
.....
[root@varnish50 ~]# varnishadm  -S /etc/varnish/secret -T 127.0.0.1:6082 
200        
-----------------------------
Varnish Cache CLI 1.0
-----------------------------
Linux,3.10.0-693.el7.x86_64,x86_64,-sfile,-smalloc,-hcritbit
varnish-4.0.5 revision 07eff4c29

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

vcl.load test7 default.vcl#编译
200        
VCL compiled.
vcl.use test7#使用
200        
VCL 'test7' now active
vcl.list#查询
200        
available       0 boot
available       0 test1
available       0 test2
available       0 test3
available       0 test4
available       0 test6
active          0 test7 #处于活动状态

客户端测试:

[root@vs ~]# curl -X PURGE http://172.16.1.50/index.html
<!DOCTYPE html>
<html>
  <head>
    <title>405 Purging not allowed for172.16.1.100</title>
  </head>
  <body>
    <h1>Error 405 Purging not allowed for172.16.1.100</h1>   #客户端ip不在响应范围内,访问purge请求返回错误
    <p>Purging not allowed for172.16.1.100</p>
    <h3>Guru Meditation:</h3>
    <p>XID: 131081</p>
    <hr>
    <p>Varnish cache server</p>
  </body>
</html>

7、使用banning方法禁止或清理缓存

(1)、手动临时清理,执行一次生效一次。
[root@varnish50 ~]# varnishadm  -S /etc/varnish/secret -T 127.0.0.1:6082 
200        

ban req.url ~ ^/javascripts#用ban命令清理
200      
ban req.url ~.js$  #用ban命令清理以.js结尾的缓存
200
(2)、调用ban函数,执行清理
[root@varnish50 ~]# vim /etc/varnish/default.vcl
.......
sub vcl_recv {

if (req.method == "BAN") {
ban("req.http.host == " + req.http.host + " && req.url == " + req.url);#客户请求的主机名加请求资源
# Throw a synthetic page so the request won't go to the backend.
return(synth(200, "Ban added"));
                    }
[root@varnish50 ~]# varnishadm  -S /etc/varnish/secret -T 127.0.0.1:6082 
200        
-----------------------------
Varnish Cache CLI 1.0
-----------------------------
Linux,3.10.0-693.el7.x86_64,x86_64,-sfile,-smalloc,-hcritbit
varnish-4.0.5 revision 07eff4c29

Type 'help' for command list.
Type 'quit' to close CLI session.   
vcl.load test8 default.vcl
200        
VCL compiled.
vcl.use test8
200        
VCL 'test8' now active

客户端测试:

[root@vs ~]# curl -X BAN  http://192.168.1.50/javascripts/test.js#使用ban方法清除指定缓存
<!DOCTYPE html>
<html>
  <head>
    <title>200 Ban added</title>
  </head>
  <body>
    <h1>Error 200 Ban added</h1>
    <p>Ban added</p>
    <h3>Guru Meditation:</h3>
    <p>XID: 65580</p>
    <hr>
    <p>Varnish cache server</p>
  </body>
</html>
[root@vs ~]# curl -I  http://192.168.1.50/javascripts/test.js
HTTP/1.1 503 Backend fetch failed
Date: Tue, 31 Jul 2018 16:48:17 GMT
Server: Varnish
Content-Type: text/html; charset=utf-8
Retry-After: 5
X-Varnish: 65588
Age: 0
Via: 1.1 varnish-v4
X-Cache: Miss form192.168.1.50 #清理后显示miss
Content-Length: 282
Connection: keep-alive

参考文献:https://www.cnblogs.com/cutemsyu/p/6051876.html

上一篇下一篇

猜你喜欢

热点阅读