varnish基本介绍

先介绍varnish的一些原理:

首先:从功能上说:varnish和squid一样是专业的cache服务。要做cache服务的话,肯定是要选择专业的cache服务,优先选择squid和varnish。
其次:它和squid又有所区别,Varnish 可以认为是内存缓存,速度一流,但是内存缓存也限制了其容量,缓存页面和图片还是可以的。

  • varnish是不能cache到本地硬盘上的。
  • Varnish可以使用正则表达式快速、批量地清除部分缓存
  • varnish的内存管理完全交给内核,当缓存内容超过内存阈值时,内核会自动将一部分缓存存入swap中让出内存。
  • varnish用来做网站和小文件的缓存,相当给力的,做图片cache之类的合适
  • varnish没有专门的存储引擎

挪威有家报社原来是12台squid,后来修改架构用varnish,2台vainish代替12台squid。

在这里插入图片描述
官方的图

一些节点的解释:
vcl_recv:收到客户端请求后判定下一步流向,根据 VCL 规则判断该请求应该 pass(vcl_pass)或是 pipe(vcl_pipe),还是进入 lookup(本地查询)。
vcl_pass:不能查缓存的,直接pass到后端主机
vcl_hit:缓存命中
vcl_miss:缓存未命中
vcl_pipe:varnish无法理解的请求,或者说请求非WEB服务
vcl_purge:缓存清理
vcl_synth:缓存修剪
vcl_fetch:对请求进行后端获取,发送请求,获得数据,并根据设置进行本地存储。
vcl_deliver:向客户端生成并发送响应报文,完成本次请求。

backend:后端服务器

一个请求的执行过程:
1、一个客户端的请求被接收了。然后就根据头信息进行判断是进入那个流向(分流)。
2、分成三种情况:
A:如果是PASS,则直接转发到后端服务器,获取到后端服务器的数据后缓存一份,发给客户端。如果服务器也找不到要请求的内容,则返回报错。
B:如果是PIPE则直接返回给客户端无法理解的请求。
C:如果是loopup,又叫本地查找,在根据头信息在本地缓存查找,如果找到了请求的信息,则触发hit,命中缓存直接发给客户端,如果没有找到miss,则发到后端服务器,依旧是缓存下来数据,发给客户端。

具体的配置:

1、代理和缓存

首先下包:
http://varnish-cache.org/releases/rel5.2.1.html

我用的是5.2.1版本的。

这个其实阿里云上也有,但是还是建议用这个下载,阿里云的那个比较复杂,要下载语言环境和源码包,还有开发套件。

安装一大堆依赖包:

[root@varnish ~]# yum install autoconf.noarch automake.noarch jemalloc-devel.x86_64 libedit-devel.x86_64 libtool.x86_64 ncurses-devel.x86_64 pcre-devel.x86_64 pkgconfig.x86_64 python-docutils.noarch python-sphinx.noarch graphviz.x86_64 -y

然后解压:

[root@varnish ~]# gunzip varnish-5.2.1.tgz
[root@varnish ~]# tar xf varnish-5.2.1.tar

这个东西比较特殊,直接tar解压解不了,要先gunzip然后才能tar。

[root@varnish ~]# cd varnish-5.2.1/

[root@varnish ~]# ./autogen.sh
检查系统环境


[root@varnish ~]# ./configure --prefix=/usr/local/varnish --enable-debugging-symbols --enable-developer-warnings
配置

[root@varnish ~]# make && make install
编译安装
[root@varnish ~]# cd /usr/local/varnish/

创建连接这样比较方便敲命令
[root@varnish ~]# ln -s /usr/local/varnish/sbin/varnishd /usr/sbin/
[root@varnish ~]# ln -s /usr/local/varnish/bin/* /usr/local/bin/

准备配置文件
varnish有2个配置文件:
一个是配置varnish全局工作模式的默认路径是/etc/varnish/varnish.params
另一个是配置varnish的缓存逻辑的,即VCL规则配置文件/etc/varnish/default.vcl

[root@varnish ~]# cp /usr/local/varnish/share/doc/varnish/example.vcl /usr/local/varnish/default.vcl
[root@varnish ~]# vim /usr/local/varnish/default.vcl

backend web1 {
    .host = "172.16.12.142";
    .port = "80";
}
这个就是后端webserver的地址和端口。

....中间略默认就好

sub vcl_deliver {
    # Happens when we have all the pieces we need, and are about to send the
    # response to the client.
    #
    # You can do accounting or modifying the final object here.
     if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT from test cache";
            }
    else {
        set resp.http.X-Cache = "MISS from test cache";
           }
     return (deliver);
     这里做了个小判断,如果命中的缓存则返回上边的,HIT.....没命中则返回下边的MISS
}

指定被监听端口启动varnish

[root@varnish ~]# varnishd -f /usr/local/varnish/default.vcl -a 0.0.0.0:80   
-f	指定peizhiwenjian
-a	指定IP端口
[root@varnish ~]# netstat -anpt | grep varnishd

然后找另一台机器测试:

先写host文件
172.16.12.141 test.apache.comIP是varnish的IP

第一次访问没有缓存,没出发 miss,也就是配置文件中下边的那个

在这里插入图片描述
第二次的时候就有缓存了:

在这里插入图片描述
可以看到HIT 了命中缓存。

varnishadm ban.url .*$ #清除所有 
varnishadm ban.url /index.html #清除 index.html 页面缓存 
varnishadm ban.url /admin/$ #清除 admin 目录缓存

其实varnish的功能很强,可以多台主机进行配置,还能进行负载均衡。这里就先不写了

内置变量汇总
 •vcl_recv
 在请求开始时候被调用,在请求已经被接收到并且解析后调用。目的就是决定是否处理这个请求,怎么处理,使用哪个后端。vcl_recv以return结束,参数可以为如下关键字:
 error code [reason]:返回错误码给客户端,丢弃请求。
 pass:转换到pass模式。控制权最后会转移到vcl_pass。
 pipe:转换到pipe模式。控制权最后会转移到vcl_pipe。
 lookup:在缓存中寻找请求对象。控制权最后会转移到vcl_hit或者vcl_miss,决定于对象是否在缓存中。
 •vcl_pipe
 当进入pipe模式的时候被调用。在这个模式中,请求会被转移到后端,后续的数据不管是从客户端还是后端来的都会以不变的方式传送,直到连接关闭为止。vcl_pipe以return结束,参数可以为如下关键字:
 error code [reason]:返回错误码给客户端,丢弃请求。
 pipe:以pipe模式执行。
 •vcl_pass
 当进入pass模式的时候会被调用。在这个模式中,请求会被传送到后端,然后后端的响应会被传送回客户端,但是响应不会进入缓存中。接下来通过相同客户端连接发起的请求会以普通的方式来处理。vcl_pass以return结束,参数可以为如下关键字:
 error code [reason]:返回错误码给客户端,丢弃请求。
 pass:以pass模式执行。
 restart:重新启动这个事务。增加了重启计数。如果重启的次数高于max_restarts,varnish会引起一个错误。
 •vcl_hash
 你如果把想把数据加入到hash中,那么调用hash_data()。vcl_hash以return结束,参数可以为如下关键字:
 hash:执行hash逻辑。
 •vcl_hit
 如果请求的对象在缓存中被找到了,那么在缓存查找结束后被调用。vcl_hit以return结束,参数可以为如下关键字:
 deliver:deliver缓存对象到客户端。控制权最后会转移到vcl_deliver。
 error code [reason]:返回错误码给客户端,丢弃请求。
 pass:切换到pass模式。控制权最后会转移到vcl_pass。
 restart:重新启动这个事务。增加了重启计数。如果重启的次数高于max_restarts,varnish会引起一个错误。
 •vcl_miss
 如果请求的对象在缓存中没有被找到,那么在缓存查找结束后被调用。目的是为了决定是否去后端获取这个请求对象,并且要选择哪个后端。vcl_miss以return结束,参数可以为如下关键字:
 error code [reason]:返回错误码给客户端,丢弃请求。
 pass:切换到pass模式。控制权最后会转移到vcl_pass。
 fetch:去后端获取请求对象。控制权最后会转移到vcl_fetch。
 •vcl_fetch
 当一个对象被成功从后端获取的时候此方法会被调用。vcl_fetch以return结束,参数可以为如下关键字:
 deliver:可能把对象放入缓存中,然后再deliver到客户端。控制权最后会转移到vcl_deliver。
 error code [reason]:返回错误码给客户端,丢弃请求。
 esi:以ESI形式来处理刚刚被获取到的对象。
 pass:切换到pass模式。控制权最后会转移到vcl_pass。
 restart:重新启动这个事务。增加了重启计数。如果重启的次数高于max_restarts,varnish会引起一个错误。
 •vcl_deliver
 当一个缓存的对象被deliver到客户端的时候,此方法会被调用。vcl_deliver以return结束,参数可以为如下关键字:
 deliver:发送对象到客户端。
 error code [reason]:返回错误码给客户端,丢弃请求。
 restart:重新启动这个事务,增加重启计数。如果重启的次数高于max_restarts,varnish会引起一个错误。
 •vcl_error
 当遇见一个错误的时候会被调用,错误可能是跟后端有关系或者内部错误。vcl_error以return结束,参数可以为如下关键字:
 deliver:发送对象到客户端。
 restart:重新启动这个事务,增加重启计数。如果重启的次数高于max_restarts,varnish会引起一个错误。

重要变量

subroutine不带参数,一般通过全局变量来实现信息的传递。

如下变量在backend中有效:
 .host:backend的主机名或者IP。
 .port:backend的端口。

如下变量在处理一个请求(例如vcl_recv)的时候可用:
 •client.ip:客户端IP地址。
 •server.hostname:服务器的主机名。
 •server.identity:服务器标示,当启动varnish的时候用”-i”参数来指定。如果varnish启动时候没有指定”-i”参数,那么server.identity会被设置为用”-n”参数所指定的实例名称。
 •server.ip:服务器IP地址。
 •server.port:服务器端口。
 •req.request:请求类型(例如“GET”,“HEAD”)。
 •req.url:请求的URL。
 •req.proto:HTTP协议版本。
 •req.backend:处理请求的后端服务器。
 •req.backend.healthy:后端是否健康。health check需要在backend的probe中进行设置。
 •req.http.header:相关的HTTP头。
 •req.hash_always_miss:强迫对于本次请求的缓存查找结果为miss。如果设置为”true”,那么varnish将会忽略任何存在的缓存对象,一直从后端重新获取资源。
 •req.hash_ignore_busy:在缓存查找时候忽略任何忙的对象。如果有两个服务器,彼此互相查找缓存内容,那么可以使用这个变量来避免潜在的死锁。

如下变量在准备一个后端请求(比如在cache miss或者pass,pipe模式)的时候可用:
 •bereq.request:请求的类型(比如“GET”,“HEAD”)。
 •bereq.url:请求的URL。
 •bereq.proto:与后端服务器交互的HTTP协议版本。
 •bereq.http.header:相关的HTTP头。
 •bereq.connect_timeout:与后端连接的超时时间。
 •bereq.first_byte_timeout:从后端返回第一个字节所需等待的秒数,在pipe模式中不可用。
 •bereq.between_bytes_timeout:从后端返回的每个字节之间的时间间隔,以秒计。在pipe模式中不可用。

如下的变量在请求对象从后端返回之后,在其被放入缓存之前可用。换句话说,也就是在vcl_fetch中可用。
 •beresp.proto:HTTP协议版本。
 •beresp.status:后端返回的HTTP状态码(例如200,302等)。
 •beresp.response:后端返回的状态内容(例如“OK”,“Found”)。
 •beresp.cacheable:如果请求的结果是可以被缓存的,那么此变量为”true”。如果HTTP状态码为200, 203, 300, 301, 302, 404410之一并且pass没有在vcl_recv中被调用,那么这个结果就是可以被缓存的。如果response的TTL和grace time都为0,那么beresp.cacheable将会为0。beresp.cacheable是可写的。
 •beresp.ttl:缓存对象的生存时间,以秒为单位,这个变量是可写的。

在对象已经存在于缓存中并被查询到的时候,一般在vcl_hit和vcl_deliver中,如下的变量(大部分是read-only)可用:
 •obj.proto:与后端交互的HTTP版本协议。
 •obj.status:后端返回的HTTP状态码。
 •obj.response:后端返回的HTTP状态内容。
 •obj.cacheable:如果对象的beresp.cacheable为”true”,那么此变量的值为”true”。除非你强制delivery,否则obj.cacheable一直为”true”。
 •obj.ttl:缓存对象的生存时间,以秒为单位,这个变量是可写的。
 •obj.lastuse:从现在到对象最近一次访问所间隔的时间,以秒为单位。
 •obj.hits:对象被发送到客户端的次数,0表示缓存查询miss了。

如下变量在决定对象hash key的时候可用:
 •req.hash:hash key被用来关联一个缓存中的对象。在读写缓存的时候都会被用到。

如下变量在准备把一个响应发送给客户端时候可用:
 •resp.proto:响应使用的HTTP协议版本。
 •resp.status:将要返回的HTTP状态码。
 •resp.response:将要返回的HTTP状态内容。
 •resp.http.header:相关的HTTP头。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值