Varnish实现缓存、后端负载均衡和状态检测
来源:互联网 发布:txt数据导入origin 编辑:程序博客网 时间:2024/05/16 17:44
简介
Varnish 是一款高性能且开源的反向代理服务器和 HTTP 加速器,其采用全新的软件体系机构,和现在的硬件体系紧密配合,与传统的 squid 相比,varnish 具有性能更高、速度更快、管理更加方便等诸多优点,很多大型的网站都开始尝试使用 varnish 来替换 squid,这些都促进 varnish 迅速发展起来。
挪威的最大的在线报纸 Verdens Gang(vg.no) 使用 3 台 Varnish 代替了原来的 12 台 Squid,性能比以前更好,这是 Varnish 最成功的应用案例。
varnish有community版本和enterprise版本。通常community版本即可够我们使用。企业版本有更多的功能。
缓存原理
Varnish 与一般服务器软件类似,分为 master 进程和 child 进程。Master 进程读入存储配置文件,调用合适的存储类型,然后创建 / 读入相应大小的缓存文件,接着 master 初始化管理该存储空间的结构体,然后 fork 并监控 child 进程。Child 进程在主线程的初始化的过程中,将前面打开的存储文件整个 mmap 到内存中,此时创建并初始化空闲结构体,挂到存储管理结构体,以待分配。Child 进程分配若干线程进行工作,主要包括一些管理线程和很多 worker 线程。
接着,开始真正的工作,varnish 的某个负责接收新 HTTP 连接线程开始等待用户,如果有新的 HTTP 连接过来,它总负责接收,然后唤醒某个等待中的线程,并把具体的处理过程交给它。Worker 线程读入 HTTP 请求的 URI,查找已有的 object,如果命中则直接返回并回复用户。如果没有命中,则需要将所请求的内容,从后端服务器中取过来,存到缓存中,然后再回复。
分配缓存的过程是这样的:它根据所读到 object 的大小,创建相应大小的缓存文件。为了读写方便,程序会把每个 object 的大小变为最接近其大小的内存页面倍数。然后从现有的空闲存储结构体中查找,找到最合适的大小的空闲存储块,分配给它。如果空闲块没有用完,就把多余的内存另外组成一个空闲存储块,挂到管理结构体上。如果缓存已满,就根据 LRU 机制,把最旧的 object 释放掉。
释放缓存的过程是这样的:有一个超时线程,检测缓存中所有 object 的生存期,如果超初设定的 TTL(Time To Live)没有被访问,就删除之,并且释放相应的结构体及存储内存。注意释放时会检查该存储内存块前面或后面的空闲内存块,如果前面或后面的空闲内存和该释放内存是连续的,就将它们合并成更大一块内存。
整个文件缓存的管理,没有考虑文件与内存的关系,实际上是将所有的 object 都考虑是在内存中,如果系统内存不足,系统会自动将其换到 swap 空间,而不需要 varnish 程序去控制。
缓存思想
实际生产中,要考虑如何提高命中率。
varnish配置
软件配置文件:/etc/varnish/varnish.params
缓存配置文件:/etc/varnish/default.vcl
varnish的管理命令:varnishadm
varnish的的软件配置文件/etc/varnish/varnish.params
,其中指定了VARNISH_ADMIN_LISTEN_ADDRESS
和VARNISH_ADMIN_LISTEN_PORT
,从字面意思来看,是管理监听地址和管理监听端口,不错,这个套接字就是管理varnish的套接字。
配置文件中还有一个监听端口,VARNISH_LISTEN_PORT=6081
,这个是varnish对外监听web请求的端口,可是为什么是6081,而不是80 端口呢?因为varnish作为缓存服务器,常常是放在nginx反代的后面,这样不面对互联网,因此就不需要监听在80端口了。
varnish的缓存配置文件是以vcl结尾的文件,在配置文件/etc/varnish/varnish.params
中指定默认的配置文件是VARNISH_VCL_CONF=/etc/varnish/default.vcl
, 和其他软件不同的是,此缓存配置文件是需要编译成二进制文件后方可以使用。这就涉及到了varnish的管理命令了。
修改缓存配置后,如何生效?
1、使用varnishadm连接到varnish,注意尽量不要退出,否则将会不见了那些编译好的编译列表 varnishadm -S /etc/varnish/secret -T [ADDRESS:]PORT
默认只需要varnishadm即可
2、对指定的缓存配置文件,默认是default.vcl进行编译
格式:vcl.load <complier_name> default.vcl
其中complier_name是自定义名称,例如此处 vcl.load test1 default.vcl
3、指定使用编译好的complier_name vcl.use test1
4、可以使用vcl.list来查看编译好的那些complier_name和其正在使用情况。
配置思路:(状态机)
VCL有多个状态引擎,状态之间存在相关性,但状态引擎彼此间互相隔离;varnish根据数据报文的流向,来设置了多个状态引擎,并且每个状态引擎可使用return(x)指明关联至哪个下一级引擎;每个状态引擎对应于vcl文件中的一个配置段,即为subroutine。
varnish 4.0:的状态引擎: vcl_init :数据包刚进入varnish时,它和vcl.fini相当于awk中的BEGIN和END关系。 vcl_recv:varnish接收报文时候。 vcl_hash :varnish进行hash查找本地是否有对应的缓存项 vcl_hit:查找缓存后,缓存命中 vcl_pass:直接将请求发给后端服务器 vcl_miss:查询缓存后未命中 vcl_pipe :用于将请求直接传递至后端主机 vcl_waiting vcl_purge:缓存对象的修剪,能执行purge操作,去除对应页面的缓存, vcl_deliver:将在缓存中找到请求的内容发送给客户端前调用此方法。 vcl_synth:合成错误返回报文vcl_fetch: 从后端主机获取内容后调用该方法,接着,通过判断获取的内容来决定是将内容放入缓存,还是直接返回给客户端。 vcl_fini:数据包发给客户端后的状态。相当于awk中的END 面向后端服务器所用的 vcl_backend_fetch vcl_backend_response vcl_backend_error
下面是最简单的状态机模型:
1、Receive 状态(vcl_recv)。也就是请求处理的入口状态,根据 VCL 规则判断该请求应该 pass(vcl_pass)或是 pipe(vcl_pipe),还是进入 lookup(本地查询)。
2.、Lookup 状态。进入该状态后,会在 hash 表中查找数据,若找到,则进入 hit(vcl_hit)状态,否则进入 miss(vcl_miss)状态。
3、Pass(vcl_pass)状态。在此状态下,会直接进入后端请求,即进入 fetch(vcl_fetch)状态
4、Fetch(vcl_fetch)状态。在 fetch 状态下,对请求进行后端获取,发送请求,获得数据,并根据设置进行本地存储。
5、Deliver(vcl_deliver)状态。将获取到的数据发给客户端,然后完成本次请求。
有了流程状态机,那么在相应的流程里,可供操作的对象有哪些呢?这里的对象可以理解为有什么变量类型可以供操作呢?
变量类型
变量分为內建变量和自定义变量。
內建变量
共5种变量类型:
1、req.*:request,表示由客户端发来的请求报文相关;
req.http.*
req.http.User-Agent, req.http.Referer, …
2、bereq.*:由varnish发往BE主机的httpd请求相关;
bereq.http.*
3、beresp.*:由BE主机响应给varnish的响应报文相关;
beresp.http.*
4、resp.*:由varnish响应给client相关;
5、obj.*:存储在缓存空间中的缓存对象的属性;只读;
自定义变量
set
unset
实验
1、强制对某类资源的请求不检查缓存
1、vcl_recv { if (req.url ~ "(?i)^/(login|admin)") { //(?i忽略大小写) return(pass); }}2、使用varnishadm来管理缓存(1)编译/etc/varnish/default.vclvcl.load test1 default.vcl(2)指定使用哪个编译结果vcl.use test13、使用curl -I ip/login/index.html来查看是否成功
2、如何设定使用多个后端主机
backend default { .host = "172.16.100.6"; .port = "80";}backend appsrv { .host = "172.16.100.7"; .port = "80";}sub vcl_recv { if (req.url ~ "(?i)\.php$") { set req.backend_hint = appsrv; } else { set req.backend_hint = default; } ...}#编译,使用某个编译的结果就不演示了,和上面的实验相同,只是test1换个名字即可
注意:在定义多个后端主机时候,必须对其进行引用,否则将会出现编译失败
3、varnish对后端web服务器负载均衡
使用前需要导入:import directors;示例:import directors; # load the directorsbackend imgsrv1 { .host = "192.168.10.11"; .port = "80";}backend imgsrv2 { .host = "192.168.10.12"; .port = "80";} backend appsrv1 { .host = "192.168.10.21"; .port = "80";}backend appsrv2 { .host = "192.168.10.22"; .port = "80";}sub vcl_init { new imgsrvs = directors.random(); imgsrvs.add_backend(imgsrv1,10); imgsrvs.add_backend(imgsrv2,20); new staticsrvs = directors.round_robin();//轮询不支持权重 appsrvs.add_backend(appsrv1); appsrvs.add_backend(appsrv2); new appsrvs = directors.hash(); appsrvs.add_backend(appsrv1,1); appsrvs.add_backend(appsrv2,1); }sub vcl_recv { if (req.url ~ "(?i)\.(css|js)$" { set req.backend_hint = staticsrvs.backend(); } if (req.url ~ "(?i)\.(jpg|jpeg|png|gif)$" { set req.backend_hint = imgsrvs.backend(); } else { set req.backend_hint = appsrvs.backend(req.http.cookie);做会话绑定 }}
4、后端主机的状态监测
后端主机的状态监测,就是每隔一定时间对后端主机发出请求,查看是否回应,如果没有回应,超过多少次没有回应,算成是后端主机不健康。
状态检测语句块
probe健康监测的内容:.url:检测时要请求的URL,默认为”/"; .request:发出的具体请求; .request = "GET /.healthtest.html HTTP/1.1" "Host: www.magedu.com" "Connection: close".window:基于最近的多少次检查来判断其健康状态; .threshold:最近.window中定义的这么次检查中至有.threshhold定义的次数是成功的;.interval:检测频度; 每隔几秒进行监测一次。.timeout:超时时长;.expected_response:期望的响应码,默认为200;企业版的还支持检测返回的具体内容
方式1示例:
probe check { .url = "/.healthcheck.html";监测是否能获得此文件,两个后端主机都要有此文件 .window = 5; .threshold = 4; .interval = 2s; .timeout = 1s;}backend default { .host = "10.1.0.68"; .port = "80"; .probe = check;}backend appsrv { .host = "10.1.0.69"; .port = "80"; .probe = check;}
方式2示例
backend BE_NAME { .host = .port = .probe = { .url= .timeout= .interval= .window= .threshold= }}
手动设定BE(后端主机)主机的状态:
在命令行管理varnishadm中:backend.set_healthsick:人工downhealthy:人工healthyauto:恢复原始probe检测状态
例如:backend.set_health default sick
- Varnish实现缓存、后端负载均衡和状态检测
- varnish负载均衡实现
- apache + varnish 实现负载均衡
- varnish反向代理服务器:安装,缓存,负载均衡
- 【nginx】负载均衡和proxy的配置--后端检测扩展
- varnish负载均衡的实现分析
- Varnish安装与配置实现负载均衡
- Nginx负载均衡+监控状态检测
- nginx配置:反向代理 负载均衡 后端健康检查 缓存
- Varnish后端主机的健康状态检查
- Varnish后端主机的健康状态检查
- Varnish后端主机的健康状态检查
- Java web 负载均衡 和 缓存
- Java web 负载均衡 和 缓存
- Nginx负载均衡+反向代理+监控状态检测
- 使用varnish做cache(高速缓存)&定义多个不同域名站点的后端服务器&把多个后端聚合为一个组并检查负载均衡
- Nginx实现HTTP负载均衡和TCP负载均衡
- windows使用nginx+memcached实现负载均衡和session或者缓存共享
- js中===与==的区别
- Mybatis一对多与多对多
- 通过 Spring + Netty + Protostuff + ZooKeeper 实现了一个轻量级 RPC 框架
- vi操作
- SpringMVC数组、集合类型参数绑定与异常处理器
- Varnish实现缓存、后端负载均衡和状态检测
- 暑假英语晨读总结
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛-A. Banana
- 【C#】进程和线程
- HashMap和ArrayMap的区别
- Spring框架的整理
- 在Ubuntu环境下配置Hadoop伪分布式模式运行环境
- 划水
- [cocos2dx_Lua]自定义本地化数据