Web架构:varnish缓存代理服务器超详细剖析

小生博客:http://xsboke.blog.51cto.com

小生 Q Q:1770058260

-------谢谢您的参考,如有疑问,欢迎交流



目录

  • varnishi简介
  • varnish配置组成

--------------------------------------  vcl内置预设变量

--------------------------------------  功能语句与对象

--------------------------------------  varnish中内置子程序

--------------------------------------  varnish缓存模式和子程序的关系

  • varnish的安装
  • varnish实例配置解析
  • 启动varnish
  • varnish acl配置解析


一、 Varnish简介

1. 作用

  • Web应用加速器,同时作为http反向缓存代理

2. 特点

  • Varnish可以使用内存也可以使用硬盘进行数据缓存
  • 支持虚拟内存的使用
  • 有精确的时间管理机制
  • 状态引擎架构:通过特定的配置语言设计不同的语句
  • 以二叉堆格式管理缓存数据

3. Varnish的优势

  • Varnish访问速度快,因为采用了“Visual Page Cache”技术,在读取数据时直接从内存中读取
  • Varnish支持更多的并发连接,因为varnish的TCP连接比squid快
  • Varnish通过管理端口,使用正则表达式批量的清除部分缓存

4. Varnish的劣势

  • 进程一旦crash或重启,缓存的数据将从内存中完全释放
  • 在多台varnish实现负载均衡时,每次请求都会落到不同的varnish服务器中,造成url请求可能会穿透到后端

    1)劣势解决方案

    A、在varnish的后端添加squid/nignx代理,这样防止了当varnish缓存被清空时,瞬间大量的请求发往web服务器

    B、在负载均衡上做url哈西,让单个url请求固定请求到一台varnish服务器上

5. Varnish的组成

1)  Management进程(管理进程)

对child进程进行管理,同时对vcl配置进行编译

2)  Child进程(子进程)

生成线程池,负责处理用户请求

6. Varnish配置组成

l  后端配置:指定后端服务器

l  ACL配置:为varnish添加访问控制列表,用于规则设置

l  Probes配置:实现后端服务器的健康检查

l  Directors配置:为varnish添加集群

l  核心子进程:为后端服务器、缓存、访问控制、错误处理等功能添

一、 arnish配置简介

1. vcl内置预设变量

  • 这些变量一般用于设置各个阶段的对象值
  • 预设变量是系统固定的,请求进入vcl子程序后便生成,这些变量可以方便子进程进行提取或者自定义
  • 格式一般为:阶段  .对象运算符值

1)阶段

  • Req:处理客户端发送的请求时使用
  • Bereq:处理varinish向后端服务器发送的请求时使用
  • Beresp:处理后端服务器响应时使用,用于varnish未缓存前
  • Resp:处理返回给客户端的响应时使用
  • Obj:处理存储在内存中的对象时使用

2)对象

3)   运算符

2. 功能语句与对象

l  一般功能语句都用于匹配对象,就是对某个对象实现什么操作

l  格式为:功能语句(对象)

1)功能语句

  • ban():清除指定对象缓存
  • call():调用子程序
  • hash_data():生成hash键值,只能在vcl_hash子程序中使用
  • new():创建一个vcl对象,只能在vcl_init子程序中使用
  • return():结束当前子程序并执行下一步动作
  • rollback():恢复http头到原来的状态,现在使用std.rollback()代替。
  • .synthetic():合成器,用于自定义一个响应内容,只能在vcl_synth和vcl_backend_error子程序中使用
  • regsub(待处理字符,正则表达式,替换为的字符):使用正则替换第一次出现的字符串
  • regsuball(待处理字符,正则表达式,替换为的字符):使用正则替换所有字符串

2)return的常用动作

语法:return(action)

  • abandon:放弃处理,并生成一个错误。
  • deliver:交付处理
  • fetch:从后端取出响应对象
  • hash:哈希缓存处理
  • lookup:从缓存中查找应答数据并返回,如果查找不到,则调用pass函数,从后端服务器调用数据。
  • ok:继续执行
  • pass:绕过缓存,直接向后端服务器调用数据
  • pipe:建立客户端和后端服务器之间的直接连接,从后端服务器调用数据
  • purge:清除缓存对象,构建响应
  • restart:重新开始
  • retry:重试后端处理
  • synth(status code,reason):合成返回客户端状态信息

3. varnish中内置子程序

  • 子进程也叫状态引擎,每一个状态引擎均有自己限定的返回动作  return (动作);  不同的动作将调用对应下一个状态引擎。
  • 我们可以把一个请求分为多个阶段,每个阶段都会调用不同的状态引擎去操作,这样,我们只要编写出相应的状态引擎,就可以控制每个请求阶段。
  • varnish内置子程序均有自己限定的返回动作  return (动作);  不同的动作将调用对应下一个子程序
  • 每个内置子程序都需要通过关键字sub进行定义

1) vcl_recv子程序

2) vcl_pipe子程序

3) vcl_pass子程序

4) vc_hit子程序

5) vcl_miss子进程

6) vcl_hash子进程

7) acl_purge子进程

8) vcl_deliver子进程

9) vcl_backend——fetch子程序

10) vcl_backend_response子程序

11) vcl_backend_error子程序

12) vcl_synth子程序

13) vcl_init子进程

14) acl_fini子进程

4. varnish缓存模式和子程序的关系

l  varnish的配置文件,就是通过各种子程序组成的,当varnish运行时,也是通过子程序的配置进行相应的操作

l 子程序的关系如下图

1) 右上角的两个图代表:加载vcl时执行vcl_init子程序,卸载vcl时执行vcl_fini子程序

2) 当vcl_recv调用 hash函数时

进入该状态后,会通过vcl_hash子程序,根据请求的url或其他信息生成hash键值,

然后查找hash键值相同的缓存数据,若找到,则进入val_hit状态,否则进入vcl_miss状态

3) 当vcl_recv调用pass 函数时

  • 当vcl_recv调用pass 函数时,pass将当前请求直接转发到后端服务器。而后续的请求仍然通过varnish处理。
  • pass (varnish)通常只处理静态页面。即只在GET 和 HEAD 类型的请求中时才适合调用pass函数。另外,需要注意的一点是,pass模式不能处理POST请求,为什么呢?因为POST请求一般是发送数据给服务器,需要服务器接收数据,并处理数据,反馈数据。是动态的,不作缓存

4) 当vcl_recv判断需要调用 pipe 函数时

  • 当vcl_recv判断需要调用 pipe 函数时,varnish会在客户端和服务器之间建立一条直接的连接,之后客户端的所有请求都直接发送给服务器,绕过varnish,不再由varnish检查请求,直到连接断开。
  • 类型是POST时用pipe,举个例子,当客户端在请求一个视频文件时,或者一个大的文档,如.zip .tar 文件,就需要用pipe模式,这些大的文件是不被缓存在varnish中的。

5) 当vcl_recv指定purge模式时

Purge模式用于清除缓存

5. 优雅模式garce mode

1) 请求合并

  • 当几个客户端请求同一个页面的时候,varnish只发送一个请求到后端服务器,然后让其他几个请求挂起并等待返回结果

2) 问题

  • 如果数以千计或更多的这种请求同时出现,那么这个等待队列将变得庞大,这将导致2类潜在问题:惊群问题(thundering herd problem),即突然释放大量的线程去复制后端返回的结果,将导致负载急速上升;没有用户喜欢等待;

3) 解决问题

  • 配置varnish在缓存对象因超时失效后再保留一段时间,以给那些等待的请求返回过去的文件内容(stale content)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14


案例:
  Sub vcl_recv {
     If (! req.backend.healthy) {        判断如果不健康
       set req.grace = 5m;varnish向前端提供5分钟的过期内容
     }
     else {                            如果健康
       set req.grace = 15s;varnish向前段提供15秒的过期内容
     }
   }
 
   sub vcl_fetch {
       set beresp.grace = 30m;将失效的缓存对象再多保留30分钟
   }

三、 varnish的安装

1. 下载varnish压缩包

有两个地方可下载

1) 通过Varnish的官方网址http://varnish-cache.org,可以在这里下载最新版本的软件。

但是有时候varnish的官网会被墙

2) GIT下载:git clone https://github.com/varnish/Varnish-Cache/var/tmp/

但是在安装时需要先使用./autogen.sh生成configure编译配置文件

2. Varnish的安装

首先安装依赖包

配置varnish

编译并安装

拷贝vcl文件

官方提供的vcl配置文件没有提示太多的配置信息,在生产环境中还是需要自己进行配置

四、 Varnish VCL实例配置解析

拓扑环境

五、 启动varnish

六、 varnish vcl配置解析

Varnish有自己的编程语法vcl,varnish启动时,会将配置文件编译为C语言,然后再执行

1. 后端服务器地址池配置及后端服务器健康检查

1)   后端服务器定义,用于varnish连接指定的后端服务器


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20


例:将监控块定义在后端服务器中
    backend web{
        .host="192.168.31.83";指定后端服务器的IP
        .port="80";后端服务器的暴露端口
        .probe={    直接追加监控块.probe是一个的参数
            .url="/";
            .timeout=2s;
         }
     }
或:先定义监控块,在定义后端服务器列表
    probe web_probe{    监控必需定义在前面,否则后端调用找不到监控块。
        .url="/";
        .timeout=2s;
    }
 
    backend web{
        .host="192.168.31.83";
        .port="80";
        .probe=web_probe;   调用外部共用监控块
    }

2)   监视器定义


1
2
3
4
5
6
7
8


例:创建健康监测,定义健康检查名称为backend_healthcheck
    probe backend_healthcheck {   创建名为backend_healthcheck的健康检查
       .url = "/";监控入口地址为/的
       .timeout = 1s;请求超时时间
       .interval = 5s;每次轮询间隔5秒
       .window = 5;轮询5次
       .threshold = 3;必须有3次轮询正常才算该节点正常
    }

3)   负载均衡群集directors

  • 负载均衡群集需要directors模块的支持,import directors
  • Directors负载均衡支持的算法:

使用random,hash 必须配置权重值,用于提高随机率


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36


例:
 
    加载directors模块
    import directors;
  
    配置后端服务器
    backend web1 {
        .host = "192.168.0.10";
        .port = "80";
        .probe = backend_healthcheck;
    }
    backend web2 {
    .host = "192.168.0.11";
    .port = "80";
    .probe = backend_healthcheck;
    }
  
    初始化处理
    sub vcl_init {           
    调用vcl_init初始化子程序创建后端主机组,即directors
        new  web_cluster =directors.round_robin();
        使用new关键字创建drector对象,使用round_robin算法
        web_cluster.add_backend(web1);
        添加后端服务器节点
        web_cluster.add_backend(web2);
    }
    
    开始处理请求
    sub vcl_recv {
    调用vcl_recv子程序,用于接收和处理请求
        set req.backend_hint = web_cluster.backend();
        选取后端
    }

说明:

  • set命令是设置变量
  • unset命令是删除变量
  • web_cluster.add_backend(backend , real );  添加后端服务器节点,backend 为后端配置别名,real 为权重值,随机率计算公式:100 * (当前权重 / 总权重)。
  • req.backend_hint是varnish的预定义变量,作用是指定请求后端节点
  • vcl对象需要使用new关键字创建,所有可创建对象都是内定的,使用前必需import,所有new操作只能在vcl_init子程序中。

2. 访问控制列表(acl)

  • 创建一个地址列表,用于后面的判断
  • 如果列表中包含了无法解析的主机地址,它会匹配任何地址。
  • 不想匹配的IP,在前面加个!即可

3. 缓存规则设置

说明:

  • X-Forwarded-For 是用来识别通过HTTP代理或负载均衡方式连接到Web服务器的客户端最原始的IP地址的HTTP请求头字段
  • 要想后端服务器记载客户端的真实IP,只在varnish中设置不行,还需要修改后端web服务器的配置(这里是apache做后端web服务器):

修改框中的变量,指定为varnish中设置的变量

七、 varnish将不同的url发送到不同的后端server

AutoIt Code


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58


import directors;   # load the directors
backend web1 {
.host = "192.168.0.10";
.port = "80";
.probe = backend_healthcheck;
}
backend web2 {
.host = "192.168.0.11";
.port = "80";
.probe = backend_healthcheck;
}
定义后端服务器web1和web2

backend img1 {
    .host = "img1.lnmmp.com";
    .port = "80";
    .probe = backend_healthcheck;
}
backend img2 {
    .host = "img2.lnmmp.com";
    .port = "80";
    .probe = backend_healthcheck;
}
定义后端服务器img1和img2

//初始化处理
sub vcl_init {            
//调用vcl_init初始化子程序创建后端主机组,即directors
    new  web_cluster = directors.round_robin(); 
    //使用new关键字创建drector对象,使用round_robin算法
      web_cluster.add_backend(web1);
      //添加后端服务器节点
      web_cluster.add_backend(web2);
    new img_cluster = directors.random();
    //创建第二个集群
      img_cluster.add_backend(img1,2); 
      添加后端服务器节点,并且设置权重值
      img_cluster.add_backend(img2,5);
}

//根据不同的访问域名,分发至不同的后端主机组
sub vcl_recv {
   if (req.http.host  ~  "(?i)^(www.)?benet.com$") { 
       如果请求头为www.benet.com或benet.com
         set  req.http.host = "www.benet.com";
         set  req.backend_hint = web_cluster.backend();  //选取后端
   } 
   elsif (req.http.host  ~  "(?i)^images.benet.com$") {
        set  req.backend_hint = img_cluster.backend();
    }
}
说明:中的i就是忽略大小写的意思。(?i)表示开启忽略大小写,而(?-i)表示关闭忽略大小写

时间: 2024-08-13 15:41:26

Web架构:varnish缓存代理服务器超详细剖析的相关文章

基于Centos 7 部署Varnish缓存代理服务器

博文结构Varnish的概述与工作原理等等安装Varnish缓存代理服务器 一.Varnish概述 1.Varnish 简介 Varnish是一款高性能且开源的反向代理服务器和HTTP加速器,其采用全新的软件体系机构,和现在的硬件体系紧密配合.与传统的squid相比,Varnish具有高性能.速度快.管理更加方便等优点,目前很多大型的网站都开始尝试使用Varnish来代替squid,这便是Varnish迅速发展的最根本的原因. Varnish的主要特征: (1)缓存代理位置:可以使用内存也可以使

linux之搭建varnish缓存代理服务器

一.varnish原理: 1)Varnish简介: varnish缓存是web应用加速器,同时也作为http反向缓存代理.你可以安装varnish在任何http的前端,同时配置它缓存内容.与传统的 squid 相比,varnish 具有性能更高.速度更快.管理更加方便等诸多优点.有一部分企业已经在生产环境中使用其作为旧版本的squid的替代方案,以在相同的服务器成本下提供更好的缓存效果,Varnish更是作为CDN缓存服务器的可选服务之一. 根据官网的介绍,Varnish的主要特性如下:http

Java Web 环境搭建步骤(超详细,包括前期安装步骤)

Java Web 环境搭建步骤 安装对应版本的JDK 配置环境变量 本人安装的路径是C盘,在path中加入C:\Program Files\Java\jdk1.8.0_65\bin 测试配置成功,cmd中输入javac,显示如下界面: 安装Tomcat 本人安装的版本是7.0.版本 测试是否安装成功,在浏览器中输入http://localhost:8080/ 显示如下图,表示安装成功. 5.  在Eclipse中启动Tomcat服务器 1)首先,选择window下面的Preferences 2)

Varnish反向代理服务器综合应用

Varnish反向代理服务器 Varnish是一个开源的轻量级Cache和反向代理软件,通常只为http提供缓存,与Squit相比,Varnish具有性能更高.速度更快.管理更方便等优点. Varnish的特点: 基于内存进行缓存,重启后数据将丢失 利用虚拟内存方式,IO性能好 支持设置0-60秒的精确缓存时间 VCL配置管理比较灵活 32位机器上只能支持最大缓存文件大小为2GB,需要更大的缓存文件只有安装64位操作系统 具有强大的管理功能 利用二叉堆管理缓存文件,可达到积极删除目的 Varni

Haproxy + Varnish 实现WEB静态页面缓存

一.缓存介绍及Haproxy+Varnish架构图: 1.)简介:现阶段的互联网时代,缓存成为一个必不可少的一环,不论是对于整体架构的优化,减少服务器的压力,加速用户访问速度,都是需要用到缓存.而缓存的种类也是很多,例如CDN,Squid,Memcached,Varnish,已经成为一个中型,大型架构中基本的实现. 2.)CDN缓存技术是根据全国各地的用户,直接缓存到离用户最近的地方. 3.)Squid是处于前端的缓存,并且可以用作为正向代理,反向代理,透明代理. 4.)Memcached主要用

Varnish缓存机制详细介绍及简单配置

Varnish是一款高性能的开源HTTP加速器,其主要用来做为反向代理中的缓存服务器使用,但其实Varnish本身也是具有反向代理功能的,但在创建连接和维持连接上,与Nginx相比差距很大,现在有一个很流行的架构就是前端用Nginx作为反向代理,后面加Varnish缓存服务器为Web服务加速 在将Varnish前先谈谈我们的浏览器缓存机制,现在的浏览器基本都具有缓存功能,它能将我们以前访问过的静态内容和可进行缓存的动态内容缓存再本地,而后在下次访问相同资源时,如果可以确认Server端的资源未发

IntelliJ IDEA 12 创建Web项目 教程 超详细版

原文:IntelliJ IDEA 12 创建Web项目 教程 超详细版 IntelliJ IDEA 12 新版本发布 第一时间去官网看了下  黑色的主题 很给力 大体使用了下  对于一开始就是用eclipse的童鞋们 估计很难从eclipse中走出来 当然 我也很艰难的走在路上 ... 首先要说一点,在IntelliJ IDEA里面“new Project” 就相当于我们eclipse的“workspace”,而“new Module”才是创建一个工程. 这个和Eclipse有很大的区别 1.官

IntelliJ IDEA 12 创建Web项目 教程 超详细版(转)

IntelliJ IDEA 12 新版本发布 第一时间去官网看了下  黑色的主题 很给力 大体使用了下  对于一开始就是用eclipse的童鞋们 估计很难从eclipse中走出来 当然 我也很艰难的走在路上 ... 首先要说一点,在IntelliJ IDEA里面“new Project” 就相当于我们eclipse的“workspace”,而“new Module”才是创建一个工程. 这个和Eclipse有很大的区别 1.官网下载下来的默认不是黑色的主题 这里需要修改一下 工具栏上的扳手图标 或

高性能负载均衡缓存web架构

高性能web架构,动静分离,静态缓存. 使用LVS实现4层负载均衡,使用KeepAlived实现LVS的HA和其他服务的HA,使用Nginx实现7层负载均衡,使用Squid实现caching proxy. nginx和squid作为服务,可以在前接嵌入lvs和keepalived.这是一个可嵌套的结构,只要你服务器足够,业务也有这个必要. 高性能web架构,高性能缓存,squid不仅缓存静态资源还可以缓存动态请求,nginx实现负载均衡或者web服务: 具体还需要根据业务规模特性的需要调整结构,