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版本的。

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

安装一大堆依赖包:

[[email protected]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

然后解压:

[[email protected]varnish ~]# gunzip varnish-5.2.1.tgz
[[email protected]varnish ~]# tar xf varnish-5.2.1.tar

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

[[email protected]varnish ~]# cd varnish-5.2.1/

[[email protected]varnish ~]# ./autogen.sh
检查系统环境


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

[[email protected]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

[[email protected]varnish ~]# cp /usr/local/varnish/share/doc/varnish/example.vcl /usr/local/varnish/default.vcl
[[email protected]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

[[email protected]varnish ~]# varnishd -f /usr/local/varnish/default.vcl -a 0.0.0.0:80   
-f	指定peizhiwenjian
-a	指定IP端口
[[email protected]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头。
版权声明:本文为n_u_l_l_原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/n_u_l_l_/article/details/103912937

智能推荐

循环

与任何程序设计语言一样Java利用条件语句与循环结构确定流程控制,一下总结一下Java中的循环语句: while do while for switch 对于golang来说: switch非常灵活。从第一个expr为true的case开始执行,如果case带有fallthrough,程序会继续执行下一条case,不会再判断下一条case的expr,如果之后的case都有fallthrough,d...

1638 统计只差一个字符的子串数目(动态规划)

1. 问题描述: 给你两个字符串 s 和 t ,请你找出 s 中的非空子串的数目,这些子串满足替换一个不同字符以后,是 t 串的子串。换言之,请你找到 s 和 t 串中恰好只有一个字符不同的子字符串对的数目。比方说, "computer" 和 "computation"...

websocket基本原理

HTTP中一个request只能有一个response。而且这个response也是被动的,不能主动发起 因此过去的服务端推送信息是通过客户端不停的轮询实现的 websocket是双向通信协议,提供了服务端主动推送信息的能力 需要客户端(浏览器)和服务端同时支持 如果经过代理的话,还需要代理支持,否则有些代理在长时间无通信时会自动切断连接 因此WS为了保证连接不被断掉,会发心跳 WebSocket...

mybatis+ehcache二级缓存

导入jar包 mapper.xml文件开启二级缓存 pojo类实现序列化接口 配置ehcache.xml 测试...

python+opencv实现图像拼接

任务 拍摄两张图片去除相同部分,拼接在一起 原图 结果 步骤 读取两张图片 使用sift检测关键点及描述因子 匹配关键点 处理并保存关键点 得到变换矩阵 图像变换并拼接 代码实现 扩展 这里对右边图像进行变换,右边变得模糊,可以修改代码对左边图像变换 这里只有两张图片拼接,可以封装实现多张图片拼接 可以修改代码实现上下图片的拼接...

猜你喜欢

python_sklearn机器学习算法系列之AdaBoost------人脸识别(PCA,决策树)

          注:在读本文之前建议读一下之前的一片文章python_sklearn机器学习算法系列之PCA(主成分分析)------人脸识别(k-NearestNeighbor,KNN)         本文主要目的是通过一个简单的小...

memmove函数与memcpy函数的模拟实现

memmove函数和memcpy函数都是在内存复制任意类型的,但是它俩也有区别。当源区域和目标区域有重复的,memmove函数会复制缓冲区重叠的部分,而memcpy相反,会报出未知错误。 下面给出两个函数的实现 首先,memmove函数。 实现的基本原理如下图。 具体代码如下: memcpy函数的实现很简单,就直接给出源代码了...

SpringFramework核心 - IOC容器的实现 - 总结

1. 概述 把Spring技术内幕第一章和第二章过了一遍,也做了一些笔记, 对IOC容器的实现有了一定皮毛理解,现在跟着源码再过一遍总结一下IOC容器的初始化,Bean的初始化的过程,做一下总结 ① IOC容器和简单工厂模式 在开始之前,先想想我们平时是怎么使用IOC容器为我们管理Bean的,假设我们要把下面的User类交给IOC容器管理 我们不想关心如何创建一个User对象实例的,仅仅在需要他的...

Python和Django的安装

个人博客导航页(点击右侧链接即可打开个人博客):大牛带你入门技术栈  一、下载并安装Python Python 官方下载地址:http://www.python.org/ftp/python/ 我们这里选择的是 Python 2.7.2 。虽然目前最新版是Python 3.2.2, 但是Django目前还不支持 Python 3.2.2。 安装步骤很简单,双击安装包开...