小生博客: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 { //初始化处理 //根据不同的访问域名,分发至不同的后端主机组 |