varnish实现的web缓存

面对大量的PV访问,web服务器的缓存功能不容小觑,缓存在互联网中的地位已经举足轻重。那么好的缓存机制对web服务来说已经不可获取,varnish的缓存功能有目共睹,那么我们似乎没理由不了解一下基于varnish是如何让实现缓存的。

varnish的官方站点:https://www.varnish-cache.org/目前最新的版本是Varnish Cache 4.0.0

不一定最新的就是最好的,在实际生产环境中稳定最重要,我们这里使用的版本是varnish-3.0.4-1.el6.x86_64.rpm。

varnish的相关知识介绍:

一:varnish主要运行两个进程:Management进程和Child进程

Management:主要实现应用新的配置、编译VCL、监控varnish、初始化varnish以及提供一个命令行接口等,探测Child进程的健康状态。

Child进程:包含多种类型的线程

1:Acceptor线程:接收新的连接请求并响应

2:Worker线程:child进程会为每个会话启动一个worker线程

3:Expiry线程:从缓存中清理过期内容

4:backend communication 构建向后端服务器构建请求报文

5:log/stats 日志记录

6:Storage/hashing :hash表的存储 缓存就是数据的键值存储

二:连接Management的接口:

1:CLI interface

2:Telnet 已废弃

3:web    商业

三:varnish的缓存存储。

1:file:使用特定的文件存储全部的缓存数据。

2:malloc:使用malloc()库调用在varnish启动时向操作系统申请指定大小的内存空间以存储缓存对象

3:persistent(experimental):与file的功能相同,但可以持久存储数据(即重启varnish数据时不会被清除);仍处于测试期。

为varnishd指定使用的缓存类型时,-s选项可接受的参数格式如下:

1:malloc[,size]

2:file[,path[,size[,granularity]]]

3:persistent,path,size

三:varnish的工作原理图:

varnish的工作是靠几个状态引擎(state engine)也叫子进程来实现的,

varnish的子进程:

1:vcl_recv  ---接收请求,并决定将后续操作交给谁
2:vcl_pipe  ---在varnish不理解client请求的时候通过pipe直接转交后端server
3:vcl_pass  ---在不缓存的请求资源的时候转交给pass
4:vcl_hash  ---在缓存请求资源的时候叫给hash
5:vcl_hit   ---varnish缓存命中请求时交给hit
6:vcl_miss  ---varnish缓存未命中时交给miss
7:vcl_deliver  ---从后端server获取到相应资源缓存到varnish,构建响应报文时交给deliver
8:vcl_fetch    ---varnish本地没有请求资源的缓存,交给fetch去后端server获取资源时交给fetch去获取。

解说:我自己理解的,语言比较通俗:

当客户请求到达varnish服务器的时候,varnish的vcl_recv先检查自己是否可以理解请求,若不能理解,则直接通过管道vcl_pipe联系后端服务器去处理,若能理解,分两种情况:1:不缓存,则vcl_recv交给pass,pass在交给vcl_pass,cvl_pass在交给vcl_fetch让vcl_fetch去后端服务器获取相应的请求资源,获取到资源以后varnish不缓存,直接响应给客户端。2:缓存,则对请求的URL做hash,hash又分hit,miss, 若hit 则varnish直接利用本地缓存通过vcl_deliver构建响应报文响应给户端,若miss,则找vcl_fetch去后端获取,获取后缓存到本地,并通过vcl_deliver响应给客户端

通过以上介绍,大家应该对varnish有个大概的了解了,下面我们就通过具体配置来实现varnish的缓存控制机制。

(1):varnish的安装:

# rpm -ivh varnish-3.0.4-1.el6.x86_64.rpm varnish-libs-3.0.4-1.el6.x86_64.rpm varnish-docs-3.0.4-1.el6.x86_64.rpm

查看rmp包生成的文件:选几个用的着的:

c

# rpm -ql varnish
/etc/rc.d/init.d/varnish  ---服务脚本
/etc/sysconfig/varnish    ---配置文件
/etc/varnish/default.vcl  ---vcl的配置文件,也是实现缓存机制的配置文件
/usr/bin/varnishadm       ---用户空间使用工具

如果我们要做web服务器的缓存及代理,还需要编辑下配置文件/etc/sysconfig/varnish

VARNISH_LISTEN_PORT=80         ---修改服务监听的端口
VARNISH_STORAGE="malloc,200M"  ---修改缓存机制使用内存,并设定其大小

启动服务

# service varnish start

启动一个webserver,/etc/varnish/default.vcl默认代理的是本地的ip,我们自己编写个.vcl的配置文件叫test.vcl配置如下:

backend web1 {             ---定义一个后端服务器叫web
  .host = "172.16.23.1";   ---后端服务器的ip
  .port = "80";            ---这个都懂
}

五:缓存代理的简单实现:

实验环境规划拓扑图:

开启varnish服务器的路由转发,并将web server的网关指向varnish的内网ip

测试是成功!

varnish的管理命令行管理工具是varnishadm

varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082   --- -S指定密钥文件的位置,-T指定登录的ip和端口,varnish默认的管理端口是6082,在/etc/sysconfig/varnish里有相关设定。
varnish> help   ---获取帮助信息
200
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列表
vcl.show <configname>                     ---查看
param.show [-l] [<param>]                 ---查看参数信息
param.set <param> <value>                 ---设定参数值
panic.show
panic.clear
storage.list                              ---显示缓存的相关信息
backend.list                              ---显示后端服务器的相关信息
backend.set_health matcher state
ban.url <regexp>
ban <field> <operator> <arg> [&& <field> <oper> <arg>]...
ban.list
varnish> status             ---查看状态
200
Child in state running
varnish> vcl.list
200
available       0 boot                         ---available 表示可用的
active          2 reload_2014-04-23T01:03:06   ---active表示激活的
varnish> vcl.show reload_2014-04-23T01:03:06   ---查看名字叫做这个的.vcl的配置文件内容

代理成功,但是我们不知道我们的请求是否是缓存,所以我们需要在响应报文中添加一个首部来获取我们的请求是否是被缓存命中的

sub vcl_deliver {
  if (obj.hits > 0) {
    set resp.http.X-Cache = "HIT";
  } else {
    set resp.http.X-Cache = "MISS";
  }
}
varnish> vcl.load test1 test.vcl
200
VCL compiled.
varnish> use test1
101
Unknown request.
Type ‘help‘ for more info.
varnish> vcl.use test1
200
varnish>

我们再次请求验证:

可以看到,缓存命中!

如果要看到是那个服务器命中的还可以在配置文件中附加一个变量server.ip

backend web1 {
  .host = "172.16.23.1";
  .port = "80";
}
sub vcl_deliver {
  if (obj.hits > 0) {
    set resp.http.X-Cache = "HIT from"+" "+server.ip;
  } else {
    set resp.http.X-Cache = "MISS";
  }
}

注意:每次加载的时候test的版本都需要改变

varnish> vcl.load test3 test.vcl
200
VCL compiled.
varnish> vcl.use test3
200

我们在看测试结果:

OK!结果很明显!

如果我们要对某些请求不做缓存处理我们则需要在vcl_recv中做URL的过滤匹配:

sub vcl_recv {
  if (req.url ~ "test.html") {
  return(pass);
}
 return(lookup);
}
varnish> vcl.load test4 test.vcl
200
VCL compiled.
varnish> vcl.use test4
200

看看效果:

OK!可以看到varnish不在缓存对test.html URL的请求。

几个简单的例子我们可以看到对缓存控制的配置基本都是在.vcl的配置文件中做配置。而且需要用到一些内置的变量。还有内置的函数:例如return()那么我们就对VCL,以及内置函数,内置变量做 简单介绍:

VCL:VCL:Varnish Configuration Language (VCL)是varnish配置缓存策略的工具,它是一种基于“域”(domain specific)的简单编程语言 varnish就是用VCL编写对缓存的处理机制的。vcl文件需要用 VCL compiler 调用C compiler编译成二进制的格式后才能由varnish调用结果

VCL语法

VCL的设计参考了C和Perl语言,因此,对有着C或Perl编程经验者来说,其非常易于理解。其基本语法说明如下:

(1)//、#或/* comment */用于注释

(2)sub $name 定义函数

(3)不支持循环,有内置变量

(4)使用终止语句,没有返回值

(5)域专用

(6)操作符:=(赋值)、==(等值比较)、~(模式匹配)、!(取反)、&&(逻辑与)、||(逻辑或)

vcl的内置函数:

vcl_recv 函数

用于接收和处理请求。当请求到达并成功接收后被调用,通过判断请求的数据来决定如何处理请求。例如如何响应、怎么响应、使用哪个后端服务器等。

此函数一般以如下几个关键字结束。

pass:表示进入 pass 模式,把请求控制权交给 vcl_pass 函数。

pipe:表示进入 pipe 模式,把请求控制权交给 vcl_pipe 函数。

lookup:表示进入 lookup 模式,把请求控制权交给 lookup 指令处理,在缓存中查找被请求的对象,  并且根据查找的结果把控制权交给函数 vcl_hit 或函数 vcl_miss。

error code [reason]:表示返回“code”给客户端,并放弃处理该请求。“code”是错误标识,例     如 200 和 405 等。“reason”是错误提示信息。

vcl_pipe 函数

此函数在进入 pipe 模式时被调用,用于将请求直接传递至后端主机,在请求和返回的内容没有改变的   情况下,将不变的内容返回给客户端,直到这个连接被关闭。

此函数一般以如下几个关键字结束。

error code [reason]。

pipe。

vcl_pass 函数

此函数在进入 pass 模式时被调用,用于将请求直接传递至后端主机。后端主机在应答数据后将应答   数据发送给客户端,但不进行任何缓存,在当前连接下每次都返回最新的内容。

此函数一般以如下几个关键字结束。

error code [reason]。

pass。

restart 重新启动流程,增加启动次数,如果重新启动次数高于 max_restarts 发出一个错误警告

vcl_hash

当您想把一个数据添加到 hash 上时,调用此函数。

此函数一般以如下几个关键字结束。

Hash。

vcl_hit 函数

在执行 lookup 指令后,在缓存中找到请求的内容后将自动调用该函数。

此函数一般以如下几个关键字结束。

deliver:表示将找到的内容发送给客户端,并把控制权交给函数 vcl_deliver。

error code [reason] 。

pass。

restart 重新启动流程,增加启动次数,如果重新启动次数高于 max_restarts 发出一个错误警告

vcl_miss 函数

在执行 lookup 指令后,在缓存中没有找到请求的内容时自动调用该方法。此函数可用于判断是否需要从后端服务器获取内容。

此函数一般以如下几个关键字结束。

fetch:表示从后端获取请求的内容,并把控制权交给 vcl_fetch 函数。

error code [reason] 。

pass。

vcl_fetch 函数

在后端主机更新缓存并且获取内容后调用该方法,接着,通过判断获取的内容来决定是将内容放入缓存,还是直接返回给客户端。

此函数一般以如下几个关键字结束。

error code [reason]。

pass。

deliver。

esi。

restart 重新启动流程,增加启动次数,如果重新启动次数高于 max_restarts 发出一个错误警告

vcl_deliver 函数

将在缓存中找到请求的内容发送给客户端前调用此方法。

此函数一般以如下几个关键字结束。

error code [reason]。

deliver。

restart 重新启动流程,增加启动次数,如果重新启动次数高于 max_restarts 发出一个错误警告

vcl_error

出现错误时调用此函数。

此函数一般以如下几个关键字结束。

deliver。

restart。

VCL 内置公共变量

VCL 内置的公共变量可以用在不同的 VCL 函数中,下面根据使用的不同阶段进行介绍

当请求到达时,可以使用的公共变量表 1 所示

表 1. 请求到达时可用公共变量

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

Varnish 在向后端主机请求时,可是用的公共变量如表 2 所示

表 2. 向后端主机请求时可用公共变量

公共变量名 含义
beresp.requset 指定请求类型,例如 GET、HEAD 等
beresp.url 表示请求地址
beresp.proto 表示客户端发起请求的 HTTP 协议版本
beresp.http.header 表示对应请求中 HTTP 头部信息
beresp.ttl 表示缓存的生存周期,cache 保留时间(s)

从 cache 或是后端主机获取内容后,可以使用的公共变量如表 3 所示

表 3. 后端主机获取内容时可使用公共变量

公共变量名 含义
obj.status 返回内容的请求状态码,例如 200、302、504 等
obj.cacheable 返回的内容是否可以缓存
obj.valid 是否有效的 HTTP 请求
obj.response 返回内容的请求状态信息
obj.proto 返回内容的 HTTP 版本
obj.ttl 返回内容的生存周期,也就是缓存时间,单位秒
obj.lastuse 返回上一次请求到现在的时间间隔,单位秒

对客户端应答时,可以使用的公共变量如表 4 所示

表 4. 对客户端相应时可使用公共变量

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

varnish,作为缓存服务器,不是所有资源都要缓存的。缓存也是有选择的缓存,那么那些资源可以缓存,那些资源不需要缓存?2:如果缓存,缓存多久?3:如果我们不想要某个缓存资源了但是却没有超出我们定义的缓存有效时间,如何手动清除?4:如果对某一资源,我们的后端服务器上多个的,怎么定义多个服务器为一组?5:如果我们的资源是分类的,如何定义不同的请求到不同的服务器上?总结下:

不缓存的资源:

1:用户的敏感信息例如认证信息不缓存

2:带cookie信息的用户请求不需要缓存,有时候反而会降低缓存命中,因为,带来cookie,hash计算的时候就根据url+cookie计算的

3:服务器端给发送的响应报文带有set-cookie信息不缓存

实现配置:请求的不缓存是在vcl_recv中配置的,服务器端的是在vcl_fetch中配置的

sub vcl_recv {
if (req.http.Authorization || req.http.Cookie) {
         return (pass);
   }
if (!(req.url ~ "wp-(login|admin)")) {
            unset req.http.cookie;
        }
}
sub vcl_fetch {
        if (!(req.url ~ "wp-(login|admin)")) {
            unset beresp.http.set-cookie;
        }
    }

服务器组的代理缓存配置:是通过directo

backend web1 {
    .host = "www.a.com";
    .port = "80";
}
director webservers random {        ---random调度方法
  .retries = 5;                     ---表示尝试找到一个 backend 的最大次数
  {
    .backend = web1;
    .weight  = 2;
  }
  {
    .backend  = {
      .host = "www.b.org";
      .port = "80";
    }
    .weight         = 3;
  }
}

后端服务器的健康状态监测:VCL 可以设置 probe 来检测一个 backend 是否健康

backend web1 {
      .host = "www.a.com";
      .port = "80";
      .probe = {
        .url = "/test.jpg";// 哪个 url 需要 varnish 请求
        .timeout = 1 s;// 等待多长时间超时
        .interval = 5s// 检查的时间间隔
             .window = 5;// 维持 5 个 sliding window 的结果
        .threshold = 3;// 至少有三次 window 是成功的,就宣告 backend 健康
      }
     }

对于资源缓时间的设定我们是在/etc/sysconfig/varnish配置文件中设定的

VARNISH_THREAD_TIMEOUT=120

对于缓存资源未到期,但是我们需要清理,是靠 purgers参数来实现手动清理的:

安全起见,我们需要对purgers进行acl的访问控制:purgers的手动清理实现配置:

acl purgers {
        “127.0.0.1”;
        “192.168.0.0”/24;
}
sub vcl_recv {
        if (req.request == “PURGE”) {
                if (!client.ip ~ purgers) {
                        error 405 “Method not allowed”;
                }
                return (lookup);
        }
}
sub vcl_hit {
        if (req.request == “PURGE”) {
                purge;
                error 200 “Purged”;
        }
}
sub vcl_miss {
        if (req.request == “PURGE”) {
                purge;
                error 404 “Not in cache”;
        }
}
sub vcl_pass {
        if (req.request == “PURGE”) {
                error 502 “PURGE on a passed object”;
        }
}

对不同资源的请求发往不同服务器的设定:

sub vcl_recv {
  if (req.url ~ "\.(jpj)$") {
      set req.backend = web2;
  }
   else{
     set req.backend = web1;
  }
}

ok,varnish的简单使用就先介绍到这里。如有不足之处,多多赐教。

varnish实现的web缓存

时间: 2024-11-16 09:51:04

varnish实现的web缓存的相关文章

Varnish之二web缓存实践

一.实验说明 操作系统说明:Centos 7.2 主机名:node-proxy  IP:192.168.2.5(模拟外网)/192.168.2.18(模拟内网)  职责:双网卡,nginx负载均衡调度器 主机名:node01      IP:192.168.2.14(模拟内网)                        职责:varnish缓存服务器 主机名:node02      IP:192.168.2.15/192.168.2.101(模拟内网)          职责:httpd静态

Varnish实现Web缓存

varnish实现Web缓存 一.varnish简介 Varnish 的作者Poul-Henning Kamp是FreeBSD的内核开发者之一,他认为现在的计算机比起1975年已经复杂许多.在1975年时,储存媒介只有两种:内存与硬盘.但现在计算 机系统的内存除了主存外,还包括了CPU内的L1.L2,甚至有L3快取.硬盘上也有自己的快取装置,因此Squid Cache自行处理物件替换的架构不可能得知这些情况而做到最佳化,但操作系统可以得知这些情况,所以这部份的工作应该交给操作系统处理,这就是 V

web缓存及varnish 使用基础

Web缓存及varnish 使用基础 ================================================================================ Web Page Cache:  1.介绍 ★概念: 缓存就是数据交换的缓冲区(称作Cache),当某一硬件要读取数据时,会首先从缓存中查找需要的数据,如果找到了则直接执行,找不到的话则从内存中找.由于缓存的运行速度比内存快得多,故缓存的作用就是帮助硬件更快地运行. ★程序的运行具有局部性特征: 时

高性能web缓存加速器---varnish

web缓存是对网页文档的临时缓存的信息技术,web缓存能有效降低带宽使用量和服务器负载,提高用户体验.为什么需要缓存呢? 经验研究发现程序的运行具有两个方面的局部性特征: 时间局部性:数据再次被访问到的几率很大 空间局部性:周围数据也可能被访问到的几率很大 根据局部性特征,将访问过的资源IO或加载到高速存储上,不再从源位置加载:另外把其周边的数据也加载到高速存储中,加速资源的访问.缓存就是使用了高速的设备和良好结构设计加速资源访问速度. 一.web缓存 web缓存加速器常常应用的于调度器之后,实

WEB缓存系统之varnish基础入门(一)

前文我们聊了下http协议里的缓存控制机制以及varnish架构组件介绍,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/12620538.html:今天我们来聊一下怎样配置使用varnish: 前边我们说到过varnish有两个配置文件,一个是/etc/varnish/varnish.params,这个配置文件主要是定义varnishd主控进程的一些运行时参数以及定义varnishd监听在那个套接字上,以及连接varnish使用的密钥文件:另外一个配置文件

Web缓存杂谈--Etag &amp; If-None-Match

一.概述 缓存通俗点,就是将已经得到的‘东东’存放在一个相对于自己而言,尽可能近的地方,以便下次需要时,不会再二笔地跑到起始点(很远的地方)去获取,而是就近解决,从而缩短时间和节约金钱(坐车要钱嘛).Web缓存,也是同样的道理,说白了,就是当你第一次访问网址时,将这个东东(representations),如html页面.图片.JavaScript文件等,存在一个离你较近的地方,当你下次还需要它时,不用再一次跋山涉水到服务器(origin servers)去获取.继而,web缓存的优势也就很明显

Web 缓存欺骗攻击技术详解

你是否曾想过你只需要访问如:https://www.paypal.com/myaccount/home/stylesheet.css或https://www.paypal.com/myaccount/settings/notifications/logo.png这样的链接就可能会泄露你的敏感数据,甚至允许攻击者控制你的帐户? Web缓存欺骗是一种新的Web攻击向量,这种攻击技术的出现使得多种Web缓存技术和框架面临风险. Web缓存和服务器反应的一点介绍 很多网站通常都倾向于使用web缓存功能(

web缓存

web缓存HTTP协议的一个核心特性,它能最小化网络流量,并且提升用户所感知的整个系统响应速度. 什么能被缓存? *Logo和商标图像 *普通的不变化的图像(例如,导航图标) *CSS样式表 *普通的Javascript文件 *可下载的内容 *媒体文件 这些文件更倾向于不经常改变,所以长时间的对他们进行缓存能获得好处. 但一些内容从不应该被缓存: *与敏感信息相关的资源(银行数据等) *用户相关且经常更改的数据

Web缓存基础:术语、HTTP报头和缓存策略

简介 对于您的站点的访问者来说,智能化的内容缓存是提高用户体验最有效的方式之一.缓存,或者对之前的请求的临时存储,是HTTP协议实现中最核心的内容分发策略之一.分发路径中的组件均可以缓存内容来加速后续的请求,这受控于对该内容所声明的缓存策略. 在这份指南中,我们将讨论一些Web内容缓存的基本概念.这主要包括如何选择缓存策略以保证互联网范围内的缓存能够正确的处理您的内容.我们将谈一谈缓存带来的好处.副作用以及不同的策略能带来的性能和灵活性的最大结合. 什么是缓存(caching)? 缓存(cach